#include <assert.h>
#include <stdarg.h>
#include <time.h>

#include "aceMesh_clang.h"
#include "aceMesh_utils.h"
#include "args.h"
#include "dma_reuse.h"
#include "slave.h"
#include "task.h"
// #include "task_dag_graph.h"
#define HASH_MULT_VALUE 11400714819323198485
extern int total_num_threads;
extern int slave_register_child_task(aceMesh_task *t);
#ifdef ACEMESH_GRAPH_BUILD_PROFILING
int first_build_nest_graph=1;
unsigned long nest_graph_build_start=0;
unsigned long nest_graph_build_end=0;
extern unsigned long buil_prof[N_BUILD_PROF];
//     #ifdef USE_COMPOSITE_TASK
// unsigned long total_start=0;
//     #endif
#endif
//extern __thread_local_fix slave_table_item slave_table[HASH_TABLE_SIZE];
__thread_local_fix void *slave_cur_super_taskptr;
__thread_local_fix ci_task *slave_cur_task;
#ifdef MULZTI_CORE_C  
 void* vector_subtasks[VECTOR_SUBSIZE];
 __thread_local_fix int subtask_num=0;
 #endif
 extern __thread_local_fix aceMesh_task *local_parent;
extern __thread_local_fix volatile int helper_message;
typedef struct tuple_addr_type {
    void *addr;
    int type;
    // int area_type;
    // int neighbor;
    // int neighbor_type;
} temp_addr_tuple;

// std::tr1::unordered_map<void *, DataAccess> slave_local_addr;
__thread_local_fix temp_addr_tuple local_slave_addr[32];
__thread_local_fix int num_slave_addr=0;
// extern __thread_local_fix int helper_flag[64];
// extern __thread_local int global_heleper[64];
#define remote_ldm(coreid,ldm_var) ((unsigned long)&ldm_var | ((unsigned long)coreid << 20 ) |(1ULL << 45))

//extern __thread_local_fix HashMap slave_local_addr;
#ifdef TASK_LIFETIME_PROFILING
extern unsigned long avr_execute_cycles[64];
#endif
#ifdef ACEMESH_PROFILING_INST
extern unsigned long inst_perf[64];
__thread_local_fix unsigned long local_inst_perf = 0;
__thread_local_fix unsigned long inst_perf_start = 0;
__thread_local_fix unsigned long inst_perf_end = 0;
#endif

#ifdef THREAD_TRACE
#include "thread_trace.h"
extern __thread_local_fix unsigned long begin_time_s;
extern __thread_local_fix unsigned long trace_time_s;
extern __thread_local_fix int trace_myid;
#endif

#ifdef ACEMESH_PARA
// extern __thread_local_fix unsigned long cur_time;
extern __thread_local_fix int global_id1, global_id2;
extern __thread_local_fix unsigned long t_init, b_build;
extern int interval;
#endif
extern __thread_local_fix double pure_task_compute_times;
extern __thread_local_fix double pure_task_dma_times;

extern volatile void *local_endtask;

inline struct task *slave_user_execute(ci_task *self)
{
   
#ifdef TASK_LIFETIME_PROFILING
    unsigned long execute_start = rtc();
#endif

#ifdef FAT_TDG
    if (self->aceMesh_task_base.task_base._endExecute) {
        //  printf("执行完的任务直接返回后继处理\n");
        return slave_execute((struct aceMesh_task *)self);
    }

#endif

#ifdef TEMP_ASSERT
    if (self->aceMesh_task_base.task_base.affinity_id > total_num_threads) assert(0);
#endif
    unsigned long cur_time = 0;
#ifdef ACEMESH_PARA
    cur_time = rtc();
    global_id1 = (cur_time - t_init - b_build) / interval;
#ifdef DEBUG
    // printf("global_id1:%d,t_init:%ld,b_build:%ld,%ld\n",global_id1,t_init,b_build,cur_time);
#endif
#endif
    // #ifdef TEMP_MODI

#ifdef DEBUG
    printf("before slave_ci_task_func,%p,%d,%d\n", self, _MYID,
           self->aceMesh_task_base.task_base.affinity_id);
    fflush(stdout);
#endif
#ifdef ACEMESH_PROFILING_INST
    penv_slave1_inst_count(&inst_perf_start);
#endif
// #ifdef DEBUG_PBH
    // if(getparent(&self->aceMesh_task_base.task_base)==NULL)
//   printf("$$$$$$$$$$$$$$$$$$执行任务%p,MYID%d\n",self,_MYID);
//   fflush(stdout);
// #endif
// #ifdef SLAVE_CONSTRUCT_HELEPR
// int tasktype=get_task_type((struct aceMesh_task *)self);
// if(tasktype==COMPOSITE_TASK){
//      printf("MYID%d任务%p是复合任务\n",_MYID,self);
//     int i;
//    for(i=8;i<8+HELPER_NUM;i++){
//      printf("MYID%d开启\n",i);
//         int *helper_begin=remote_ldm(i, helper_flag[i]);
//         *helper_begin=1;
//         // int *helper_begin1=remote_ldm(i, global_heleper[i]);
//         // *helper_begin1=1;
//    }
   
   
// }
// #endif
//  printf("before_slave_ci_task_func%p\n",self);
#ifdef TEMP_ENDTASK_SLAVE
// printf("*********从核endtask%p\n",local_endtask);
if(self!=local_endtask)
#endif
  self->slave_ci_task_func(self->ci_args);
//   printf("end_slave_ci_task_func%p\n",self);
// #ifdef DEBUG_PBH
//    if(getparent(&self->aceMesh_task_base.task_base)==NULL)
//   printf("$$$$$$$$$$$$$$$$$$执行任务完毕%p,线程%d\n",self,_MYID);
    // fflush(stdout);
            // flush_slave_cache();

// #endif
#ifdef FAT_TDG
// slave_my_mutex_lock(&(self->aceMesh_task_base.task_base.countlock));
    self->aceMesh_task_base.task_base._endExecute = 1;
// slave_my_mutex_unlock(&(self->aceMesh_task_base.task_base.countlock));
//   slave_set_access_state(1, &(self->aceMesh_task_base.task_base._endExecute));
#ifdef DEBUG_PBH
  if(getparent(&self->aceMesh_task_base.task_base)!=NULL)
 printf("子任务%p父任务%p执行完毕MYID%d\n",self,getparent(&self->aceMesh_task_base.task_base),_MYID);
#endif
#endif

#ifdef ACEMESH_PROFILING_INST
    penv_slave1_inst_count(&inst_perf_end);
    local_inst_perf += (inst_perf_end - inst_perf_start);
#endif
// #endif
#ifdef ACEMESH_PARA
    cur_time = rtc();
    global_id2 = (cur_time - t_init - b_build) / interval;
//    if(global_id1 < 0 || global_id2 < 0 || global_id1 > global_id2)
//        assert (0);
#endif

#ifdef TASK_LIFETIME_PROFILING
    unsigned long execute_end = rtc();
    if (avr_execute_cycles[_MYID] != 0) {
        avr_execute_cycles[_MYID] += (execute_end - execute_start);
        avr_execute_cycles[_MYID] /= 2;
    } else {
        avr_execute_cycles[_MYID] = execute_end - execute_start;
    }
#endif
    //   printf("%d_slave_user_execute:%p\n",_MYID,self);
    // struct task*temp=slave_execute((struct aceMesh_task*)self);
    
#ifdef FAT_TDG
// printf("Execute%d\n",self->aceMesh_task_base.task_base._endExecute);
    if (self->aceMesh_task_base.task_base._countdownToBeWokenUp == -1 ||
    self->aceMesh_task_base.task_base._endExecute) { 
        //  asm volatile ("memb\n");
//    printf("execute4\n");
        return slave_execute((struct aceMesh_task *)self);
    } else {
     //       printf("execute5\n");
        return NULL;
    }
#endif
    
    // printf("%d_before_return_temp\n",_MYID);
    // return temp;
}


static void slave_acemesh_do_push(int argc, void *addr, int area_flag, va_list *p_args, int type)
{

    // printf("begin_acemesh_do_push\n");
        //  slave_getEndBlock(_MYID);
#ifdef ACEMESH_GRAPH_BUILD_PROFILING
    if(first_build_nest_graph==1){
        nest_graph_build_start=rtc();
        //printf("cur_slave_acemesh_do_push =%lf\n",nest_graph_build_start);
        first_build_nest_graph=0;
    }
#endif
#ifdef THREAD_TRACE_LEVEL_1
    // trace_time = rtc() - begin_time;
    // trace_print(trace_time, '0', RTS_push_addr);
#endif
#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef COARSE_PROF
    unsigned long push_start = rtc();
#endif
#endif
#ifdef NEST_UNIQUE_TUPLES
//子图需要去重吗？？
    local_slave_addr[num_slave_addr].addr=addr;
    //printf("@收集数据流地址%p\n",local_slave_addr[num_slave_addr].addr);
    local_slave_addr[num_slave_addr].type=type;
    num_slave_addr++;
    assert(num_slave_addr<=32);
    int i, j, k;
    //printf("num_slave_addr大小%d\n",num_slave_addr);
    for (i = 0; i < num_slave_addr; ++i) {
        for (j = i + 1; j <num_slave_addr;) {
            if (local_slave_addr[i].addr == local_slave_addr[j].addr) {
                if (local_slave_addr[i].type != local_slave_addr[j].type)
                local_slave_addr[i].type=INOUT;
                // 移动数组元素覆盖重复的元素
                for (k = j; k < num_slave_addr - 1; ++k) {
                    local_slave_addr[k].addr = local_slave_addr[k + 1].addr;
                }
                // 减少数组大小
                --num_slave_addr;
            } else {
                ++j;
            }
        }
    }
//printf("去重后num_slave_addr大小%d\n",num_slave_addr);
    //  for (i = 0; i < num_slave_addr; ++i){
    //   // printf("@去重后的数据流地址%p\n",local_slave_addr[i].addr);
    //  }
#else
//printf("*****slave do push *****\n");
 //printf("收集数据流地址%p\n",addr);
    //addr_tuple local_slave_addr[1600];
    // addr_tuple item;
    // item.addr=addr;
    // item.type=type;
    local_slave_addr[num_slave_addr].addr=addr;
    //printf("@收集数据流地址%p\n",local_slave_addr[num_slave_addr].addr);
    local_slave_addr[num_slave_addr].type=type;
    num_slave_addr++;
    assert(num_slave_addr<32);
//printf("***** end do push *****\n");

#endif
// printf("end do push\n");
#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef COARSE_PROF
    buil_prof[SUB_ARGS_TRANS] += (rtc() - push_start);
#endif
#endif
#ifdef THREAD_TRACE_LEVEL_1
    // trace_time = rtc() - begin_time;
    // trace_print(trace_time, '0', RTS_event_end);
#endif
}

extern void acemesh_push_wrlist(int argc, void *addr, int area_flag, ...)
{
    va_list args;
    va_start(args, area_flag);
    slave_acemesh_do_push(argc, addr, area_flag, &args, INOUT);
    va_end(args);
}

extern void acemesh_push_rlist(int argc, void *addr, int area_flag, ...)
{
    va_list args;
    va_start(args, area_flag);
    slave_acemesh_do_push(argc, addr, area_flag, &args, IN);
    va_end(args);
}

extern void acemesh_push_wlist(int argc, void *addr, int area_flag, ...)
{
    va_list args;
    va_start(args, area_flag);
    slave_acemesh_do_push(argc, addr, area_flag, &args, OUT);
    va_end(args);
}

void _register_task(ci_task *_task)
{
#ifdef THREAD_TRACE
    // trace_time = rtc() - begin_time;
    // trace_print(trace_time, '0', RTS_register_task);
#endif

    slave_register_child_task(&(_task->aceMesh_task_base));
    // if (taskptr) {
    //     task_dag_graph &nested_graph = ((aceMesh_composite_task *)taskptr)->graph;
    //     nested_graph.register_task(&(_task->aceMesh_task_base), local_vector);
    // } else {
    //     task_graph.register_task(&(_task->aceMesh_task_base), local_vector);
    // }
#ifdef BUFF_SEG
    int temp_affinity = (struct *)_task->affinity_id;
    if (temp_affinity < 0 || temp_affinity > sche_num_threads ||
        temp_affinity == sche_num_threads - 1) {
        printf("error affinity\n");
        assert(0);
    }
#endif

// #ifdef ACEMESH_SCHEDULER_PROFILING
//     total_ntasks_register++;
// #endif
#ifdef THREAD_TRACE
    // trace_time = rtc() - begin_time;
    // trace_print(trace_time, '0', RTS_event_end);
#endif
}

void _task_gen(void *taskptr, ci_task *_task)
{

#ifdef MULZTI_CORE_C  
    vector_subtasks[subtask_num]= (unsigned long) _task;
    subtask_num++;
    assert(subtask_num<VECTOR_SUBSIZE);
    aceMesh_task *parent = (aceMesh_task *)local_parent;
    slave_initprecount(&(_task->aceMesh_task_base.task_base));
    if (parent != NULL) {  
          slave_setparent(&(_task->aceMesh_task_base.task_base), &(parent->task_base)); 
     }
#endif

#ifdef NEST_UNIQUE_TUPLES
slave_initTaskDataAccess(&(_task->aceMesh_task_base.task_base),num_slave_addr);//这里需要额外+32,或者加一个别的数字???
    //slave_initTaskDataAccess(&(_task->aceMesh_task_base.task_base),local_slave_addr.length()+neighbor_addrs.length());//这里需要额外+32,或者加一个别的数字???
   //printf("slave_initTaskDataAccess完成\n");
   struct TaskDataAccesses *local_access=&(_task->aceMesh_task_base.task_base._dataAccesses);
    int i;
    int j;
     int cindex=local_access->_currentIndex;
    for(i=0; i<num_slave_addr; i++)
    {
        
        //printf("getDataAccesses\n");
        struct DataAccess *temp_accessArray=&(local_access->_accessArray[cindex]);
#ifdef MULZTI_CORE_C
        int domain_id=_MYID;
        slave_my_mutex_unlock(&(temp_accessArray->mutex_access));
        //  temp_accessArray->_originator=&(_task->aceMesh_task_base.task_base);
        //  slave_send_elem2helper(domain_id, temp_accessArray, local_slave_addr[i].addr, local_slave_addr[i].type); 
         slave_send_elem2helper(domain_id, temp_accessArray, local_slave_addr[i].addr, local_slave_addr[i].type,_task);
#else
        local_access->_addressArray[cindex]=local_slave_addr[i].addr;
        slave_initialize(temp_accessArray,local_slave_addr[i].type,&(_task->aceMesh_task_base.task_base),INITED,0);
#endif        
        //printf("@任务地址%p,类型%d,@@数据流地址%p\n",temp_accessArray->_originator,local_slave_addr[i].type,local_slave_addr[i].addr);
        //printf("slave_initialize\n");
        cindex++;
    } 
    local_access->_currentIndex = cindex;
#if defined( ACEMESH_GRAPH_BUILD_PROFILING) && defined (FINE_PROF)
unsigned long f_end=rtc();
buil_prof[SUB_FAT_TASK_GEN]+=(f_end-r_start);
#endif
#else

slave_initTaskDataAccess(&(_task->aceMesh_task_base.task_base),num_slave_addr);//这里需要额外+32,或者加一个别的数字???
    //slave_initTaskDataAccess(&(_task->aceMesh_task_base.task_base),local_slave_addr.length()+neighbor_addrs.length());//这里需要额外+32,或者加一个别的数字???
//    printf("slave_initTaskDataAccess完成\n");
#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef FINE_PROF
     unsigned long r_start = rtc();
#endif
#endif
    int i;
    int j;    
    struct TaskDataAccesses *local_access=&(_task->aceMesh_task_base.task_base._dataAccesses);

    int cindex=local_access->_currentIndex;
  #if defined( ACEMESH_GRAPH_BUILD_PROFILING) && defined (FINE_PROF)
unsigned long f_end=rtc();
buil_prof[SUB_FAT_TASK_GEN]+=(f_end-r_start);
#endif
    // printf("num_slave_addr%d\n",num_slave_addr);   
    for(i=0; i<num_slave_addr; i++)
    {
        //printf("getDataAccesses\n");
        // struct TaskDataAccesses *local_access=&(_task->aceMesh_task_base.task_base._dataAccesses);
        struct DataAccess *temp_accessArray=&(local_access->_accessArray[cindex]);
        
#ifdef MULZTI_CORE_C
        int domain_id=_MYID;
        slave_my_mutex_unlock(&(temp_accessArray->mutex_access));
        //  temp_accessArray->_originator=&(_task->aceMesh_task_base.task_base);
        //  slave_send_elem2helper(domain_id, temp_accessArray, local_slave_addr[i].addr, local_slave_addr[i].type); 
         slave_send_elem2helper(domain_id, temp_accessArray, local_slave_addr[i].addr, local_slave_addr[i].type,_task);
#else
        local_access->_addressArray[cindex]=local_slave_addr[i].addr;
        slave_initialize(temp_accessArray,local_slave_addr[i].type,&(_task->aceMesh_task_base.task_base),INITED,0);
#endif
        //printf("@任务地址%p,类型%d,@@数据流地址%p\n",temp_accessArray->_originator,local_slave_addr[i].type,local_slave_addr[i].addr);
        //printf("slave_initialize\n");
       
        cindex++;
    } 

    local_access->_currentIndex = cindex;

     //printf("#####after_local_slave_addr\n");
#endif
//printf("after cur_task\n");

#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef FINE_PROF
     unsigned long r_neib_start = rtc();
#endif
#endif

#ifndef MULZTI_CORE_C  
   // printf("#######before slave register task\n");
    slave__register_task(_task);
   // printf("#######end slave register task\n");
#endif

#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef FINE_PROF
    unsigned long r_neib_end = rtc();
    buil_prof[SUB_REG_TASK_IN] += (r_neib_end - r_neib_start);
#endif
#endif
   // printf("after_register_task\n");

    for(j=0; j<num_slave_addr; j++){
        local_slave_addr[j].addr=NULL;
        local_slave_addr[j].type=0;
    }
    num_slave_addr=0;

//printf("after_hashclear\n");    
#ifdef ACEMESH_GRAPH_BUILD_PROFILING
    #ifdef FINE_PROF
        buil_prof[SUB_VEC_CLEAR] += (rtc() - r_neib_end);
    #endif
#endif
}

void _task_gen_with_neighbors(void *taskptr, ci_task *_task)
{
#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef FINE_PROF
     unsigned long r_start = rtc();
#endif
#endif
// #ifdef NO_PARALLEL
//     slave_cur_task = _task;
// #else
//     (ci_taski *)&local_cur_task = &(slave_cur_task.local());
//     local_cur_task = _task;
// #endif
    // addr_tuple item;
    // item.addr = NULL;
    // item.area_type =
    //     NORMAL;  //!!NOTE, same as UNSHADE, see comments in get_unshade_addr(),by chenli
    // item.type = INOUT_NONE;
    // item.neighbor = NEIGHBOR_ALL;
    // item.neighbor_type = IN;

    int neighbor_num = 0;
    void *neighbor_addrs[MAX_NEIGHBORS];
    slave_get_neighbor(_task, neighbor_addrs, &neighbor_num);

#ifdef NEST_UNIQUE_TUPLES
  //addr_tuple local_slave_addr[1600];
   // printf("@num_slave_addr%d\n",num_slave_addr);
     //printf("slave_initTaskDataAccess开始\n");
    slave_initTaskDataAccess(&(_task->aceMesh_task_base.task_base),num_slave_addr+neighbor_num);
    //printf("slave_initTaskDataAccess完成\n");
    int i;
    int j;
     
    struct TaskDataAccesses *local_access=&(_task->aceMesh_task_base.task_base._dataAccesses);
    int cindex=local_access->_currentIndex;
    for(i=0; i<num_slave_addr; i++)
    {
        //printf("getDataAccesses\n");
        struct DataAccess *temp_accessArray=&(local_access->_accessArray[cindex]);
        local_access->_addressArray[cindex]=local_slave_addr[i].addr;
        slave_initialize(temp_accessArray,local_slave_addr[i].type,&(_task->aceMesh_task_base.task_base),INITED,0);
    //    printf("@任务地址%p,类型%d,@@数据流地址%p\n",temp_accessArray->_originator,local_slave_addr[i].type,local_slave_addr[i].addr);
        cindex++;
    }   
    local_access->_currentIndex = cindex;
     //printf("#####after_local_slave_addr\n");
    for(j=0; j<neighbor_num; j++) { //local_access
       // struct TaskDataAccesses *local_access=&(_task->aceMesh_task_base.task_base._dataAccesses);;
        struct DataAccess *temp_accessArray=&(local_access->_accessArray[cindex]);
        local_access->_addressArray[cindex]=neighbor_addrs[j];
        slave_initialize(temp_accessArray,IN,&(_task->aceMesh_task_base.task_base),INITED,0);
        // printf("#任务地址%p,类型%d,##数据流地址%p\n",temp_accessArray->_originator,IN,neighbor_addrs[j]);
        cindex++;
    }
    local_access->_currentIndex = cindex;
   
     //printf("#####after_neighbor_addrs\n");
    //printf("num_slave_addr%d\n",num_slave_addr);
    //printf("neighbor_num%d\n",neighbor_num);
#if defined( ACEMESH_GRAPH_BUILD_PROFILING) && defined (FINE_PROF)
unsigned long f_end=rtc();
buil_prof[SUB_FAT_TASK_GEN]+=(f_end-r_start);
#endif
#else
    slave_initTaskDataAccess(&(_task->aceMesh_task_base.task_base),num_slave_addr+neighbor_num);

    int i;
    int j;
    struct TaskDataAccesses *local_access=&(_task->aceMesh_task_base.task_base._dataAccesses);
    int cindex=local_access->_currentIndex;
    for(i=0; i<num_slave_addr; i++)
    {
        //struct TaskDataAccesses *local_access=&(_task->aceMesh_task_base.task_base._dataAccesses);
        struct DataAccess *temp_accessArray=&(local_access->_accessArray[cindex]);
        local_access->_addressArray[cindex]=local_slave_addr[i].addr;
        slave_initialize(temp_accessArray,local_slave_addr[i].type,&(_task->aceMesh_task_base.task_base),INITED,0);
        cindex++;
    }   
 
    for(j=0; j<neighbor_num; j++) { 
        //struct TaskDataAccesses *local_access=&(_task->aceMesh_task_base.task_base._dataAccesses);
        struct DataAccess *temp_accessArray=&(local_access->_accessArray[cindex]);
        local_access->_addressArray[cindex]=neighbor_addrs[j];
        slave_initialize(temp_accessArray,IN,&(_task->aceMesh_task_base.task_base),INITED,0);
        cindex++;
    }

#if defined( ACEMESH_GRAPH_BUILD_PROFILING) && defined (FINE_PROF)
unsigned long f_end=rtc();
buil_prof[SUB_FAT_TASK_GEN]+=(f_end-r_start);
#endif

#endif

#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef FINE_PROF
     unsigned long r_neib_start = rtc();
#endif
#endif
    // printf("#######before slave register task\n");
    slave__register_task(_task);
    // printf("#######end slave register task\n");
    //  slave_getEndBlock(_MYID);
#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef FINE_PROF
    unsigned long r_neib_end = rtc();
    buil_prof[SUB_REG_TASK_IN] += (r_neib_end - r_neib_start);
#endif
#endif

    for(j=0; j<num_slave_addr; j++){
        local_slave_addr[j].addr=NULL;
        local_slave_addr[j].type=0;
    }
    num_slave_addr=0;



#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef FINE_PROF
    buil_prof[SUB_VEC_CLEAR] += (rtc() - r_neib_end);
#endif
#endif
}

void acemesh_task_generator(void *taskfptr, void *args, unsigned int args_size)
{
#ifdef TASK_LIFETIME_PROFILING
    // unsigned long gene_start = rtc();
#endif

#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef COARSE_PROF
    unsigned long b_start = rtc();
#endif
#endif
    TASK_FUNCPTR funcptr = (TASK_FUNCPTR)taskfptr;
    ci_task *_task;
#ifdef MEMORY_POOL
    // alog_debug("sizeof comptask: %u", sizeof(ci_task));
    // _task = (ci_task *)(sizeof(ci_task),_MYID);
    _task = (ci_task *)slave_acemesh_myalloc_aligned_16(sizeof(ci_task),_MYID);  
    // alog_debug("addr of _task: %x", _task);
#else
#ifdef TARG_SW5
    _task = (ci_task *)malloc(sizeof(ci_task));
#elif TARG_SW9
   // _task = (ci_task *)libc_uncached_aligned_malloc(sizeof(ci_task));
    _task = (ci_task *)slave_my_malloc_aligned(sizeof(ci_task));
#else
    assert(0);
#endif
#ifdef DEBUG
    printf("generator_task=%p\n", _task);
    fflush(stdout);
#endif
#endif
   // printf("$$$$$task:%p\n",_task);
    slave_ci_task_constructor(_task, funcptr);
    slave_define(_task, args, args_size);
#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef COARSE_PROF
    unsigned long b_end = rtc();
    buil_prof[SUB_TASK_CONSTR] += (b_end - b_start);
#endif
#endif
    slave__task_gen(slave_cur_super_taskptr, _task);
#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef COARSE_PROF
    buil_prof[SUB_TASK_GENE] += (rtc() - b_end);
#endif
#endif
   // printf("before slave_ci_task in task gen\n");
//_task->slave_ci_task_func(_task->ci_args);    
// printf("after_slave__task_gen\n"); 
   // #ifdef TASK_LIFETIME_PROFILING
    //     unsigned long gene_end = rtc();
    //     if (avr_generate_cycles != 0) {
    //         avr_generate_cycles += (gene_end - gene_start);
    //         avr_generate_cycles /= 2;
    //     } else {
    //         avr_generate_cycles = gene_end - gene_start;
    //     }
    // #endif
#ifndef SLAVE_CONSTRUCT_HELEPR
#ifdef ACEMESH_GRAPH_BUILD_PROFILING  
if(first_build_nest_graph==0){ 
    nest_graph_build_end=rtc();
    first_build_nest_graph=1;
    double time=(double)(nest_graph_build_end-nest_graph_build_start)/MFREQ ;
    // printf("cur_task_nested_graph_time =%lf\n",time);
    buil_prof[BUILD_SUBTASK]+=(nest_graph_build_end-nest_graph_build_start);
}
#endif
#endif
}
void acemesh_task_generator_with_neighbors(void *taskfptr, void *args, unsigned int args_size,
                                           void *cxx_this_pointer, void *get_neighbors_funcptr,
                                           void *neighbor_args)
{
      //printf("*********调用acemesh_task_generator_with_neighbors*******\n");
       //fflush(stdout);
        
#ifdef TASK_LIFETIME_PROFILING
    // unsigned long gene_start = rtc();
#endif

#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef COARSE_PROF
    unsigned long b_start = rtc();
#endif
#endif

    TASK_FUNCPTR funcptr = (TASK_FUNCPTR)taskfptr;

    ci_task *_task;
#ifdef MEMORY_POOL
    // alog_debug("sizeof comptask: %u", sizeof(ci_task));
    // printf("before_task_memory_Pool%d\n",_MYID);
    _task = (ci_task *)slave_acemesh_myalloc_aligned_16(sizeof(ci_task),_MYID);  //
    //printf("after_task_memory_Pool\n");
    // alog_debug("addr of _task: %x", _task);
#else
#ifdef TARG_SW5
    _task = (ci_task *)malloc(sizeof(ci_task));
#elif TARG_SW9
    //_task = (ci_task *)libc_uncached_aligned_malloc(sizeof(ci_task));
    _task = (ci_task *)slave_my_malloc_aligned(sizeof(ci_task));
#else
    assert(0);
#endif
#endif
#ifdef DEBUG
    printf("create_task=%p\n", _task);
    printf("generator_with_neighbor_task=%p\n", _task);
    fflush(stdout);
#endif
// printf("enter_slave_ci_task_constructor\n");
    slave_ci_task_constructor(_task, funcptr);
// printf("enter_slave_define\n");
    slave_define(_task, args, args_size);
// printf("enter_slave_define_neighbors\n");
    slave_define_neighbors(_task, cxx_this_pointer, get_neighbors_funcptr, neighbor_args);
#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef COARSE_PROF
    unsigned long b_end = rtc();
    buil_prof[SUB_TASK_CONSTR] += (b_end - b_start);
#endif
#endif
//printf("enter_slave__task_gen_with_neighbors\n");
    slave__task_gen_with_neighbors(slave_cur_super_taskptr, _task);
    //printf("out_slave__task_gen_with_neighbors\n");
#ifdef ACEMESH_GRAPH_BUILD_PROFILING
#ifdef COARSE_PROF
    buil_prof[SUB_TASK_GENE] += (rtc() - b_end);
#endif
#endif
// printf("*********结束调用acemesh_task_generator_with_neighbors*******\n");
    // #ifdef TASK_LIFETIME_PROFILING
    //     unsigned long gene_end = rtc();
    //     if (avr_generate_cycles != 0) {
    //         avr_generate_cycles += (gene_end - gene_start);
    //         avr_generate_cycles /= 2;
    //     } else {
    //         avr_generate_cycles = gene_end - gene_start;
    //     }
    // #endif
        //  slave_getEndBlock(_MYID);
#ifndef SLAVE_CONSTRUCT_HELEPR
#ifdef ACEMESH_GRAPH_BUILD_PROFILING  
        if(first_build_nest_graph==0){ 
            nest_graph_build_end=rtc();
            first_build_nest_graph=1;
            double time=(double)(nest_graph_build_end-nest_graph_build_start)/MFREQ ;
           // printf("cur_task_nested_graph_time =%lf\n",time);
            buil_prof[BUILD_SUBTASK]+=(nest_graph_build_end-nest_graph_build_start);
        }
#endif
#endif
}

#ifdef THREAD_TRACE
void slave_acemesh_trace_print(const char event_name[])
{
    trace_time_s = rtc() - begin_time_s;
    slave_trace_print(trace_time_s, trace_myid, event_name);
}
#endif

void slave_acemesh_add_task_compute_time_(unsigned long *t)
{
    pure_task_compute_times += (double)(*t) / SFREQ;
}
void slave_acemesh_add_task_dma_time_(unsigned long *t)
{
    pure_task_dma_times += (double)(*t) / SFREQ;
}
void slave_acemesh_wait_reply(int *reply, int count)
{
#ifdef TARG_SW5
    slave_acemesh_my_wait(reply, count);
#elif TARG_SW9
    athread_dma_wait_value(reply, count);
#endif
}
void slave_acemesh_wait_reply_(int *reply, int count)
{
#ifdef TARG_SW5
    slave_acemesh_my_wait(reply, count);
#elif TARG_SW9
    athread_dma_wait_value(reply, count);
#endif
}

void slave_if_is_ldm_overflow(int ldm_size, char *file_name)
{
#ifdef TARG_SW5
    if (ldm_size >= 64) {
#elif TARG_SW9
    if (ldm_size >= 64) {
#endif
        printf("ERROR: LDM overflow in file %s.f90\n", file_name);
    }
}

void slave_if_is_full_size_dim_1d(char *array_name, int array_name_len, char *file_name,
                                  int file_name_len, int ldm_dim1_ub, int ldm_dim1_lb,
                                  int orig_dim1_ub, int orig_dim1_lb, int is_local)
{
    char *a;
    char *f;
    a = (char *)malloc(array_name_len);
    f = (char *)malloc(file_name_len);
    strncpy(a, array_name, array_name_len);
    strncpy(f, file_name, file_name_len);
    if ((ldm_dim1_ub - ldm_dim1_lb + 1) * 8 / 1024 >= 10) {
        if (is_local) {
            printf(
                "ATTENTION : the array %s is local and is bigger than 10K in file %s.f90 is FULL "
                "size. \n",
                a, f);
        } else {
            if (ldm_dim1_ub == orig_dim1_ub && ldm_dim1_lb == orig_dim1_lb) {
                printf("ATTENTION : the dim(s) of array %s in file %s.f90 is FULL size. \n", a, f);
            }
        }
    }
}

void slave_if_is_full_size_dim_2d(char *array_name, int array_name_len, char *file_name,
                                  int file_name_len, int ldm_dim1_ub, int ldm_dim1_lb,
                                  int orig_dim1_ub, int orig_dim1_lb, int ldm_dim2_ub,
                                  int ldm_dim2_lb, int orig_dim2_ub, int orig_dim2_lb, int is_local)
{
    char *a;
    char *f;
    a = (char *)malloc(array_name_len);
    f = (char *)malloc(file_name_len);
    strncpy(a, array_name, array_name_len);
    strncpy(f, file_name, file_name_len);
    if ((ldm_dim1_ub - ldm_dim1_lb + 1) * (ldm_dim2_ub - ldm_dim2_lb + 1) * 8 / 1024 >= 10) {
        if (is_local) {
            printf(
                "ATTENTION : the array %s is local and is bigger than 10K in file %s.f90 is FULL "
                "size. \n",
                a, f);
        } else {
            if ((ldm_dim1_ub == orig_dim1_ub && ldm_dim1_lb == orig_dim1_lb) ||
                (ldm_dim2_ub == orig_dim2_ub && ldm_dim2_lb == orig_dim2_lb)) {
                printf("ATTENTION : the dim(s) of array %s in file %s.f90 is FULL size. \n", a, f);
            }
        }
    }
}

void slave_if_is_full_size_dim_3d(char *array_name, int array_name_len, char *file_name,
                                  int file_name_len, int ldm_dim1_ub, int ldm_dim1_lb,
                                  int orig_dim1_ub, int orig_dim1_lb, int ldm_dim2_ub,
                                  int ldm_dim2_lb, int orig_dim2_ub, int orig_dim2_lb,
                                  int ldm_dim3_ub, int ldm_dim3_lb, int orig_dim3_ub,
                                  int orig_dim3_lb, int is_local)
{
    char *a;
    char *f;
    a = (char *)malloc(array_name_len);
    f = (char *)malloc(file_name_len);
    strncpy(a, array_name, array_name_len);
    strncpy(f, file_name, file_name_len);
    if ((ldm_dim1_ub - ldm_dim1_lb + 1) * (ldm_dim2_ub - ldm_dim2_lb + 1) *
            (ldm_dim3_ub - ldm_dim3_lb + 1) * 8 / 1024 >=
        10) {
        if (is_local) {
            printf(
                "ATTENTION : the array %s is local and is bigger than 10K in file %s.f90 is FULL "
                "size. \n",
                a, f);
        } else {
            if ((ldm_dim1_ub == orig_dim1_ub && ldm_dim1_lb == orig_dim1_lb) ||
                (ldm_dim2_ub == orig_dim2_ub && ldm_dim2_lb == orig_dim2_lb) ||
                (ldm_dim3_ub == orig_dim3_ub && ldm_dim3_lb == orig_dim3_lb)) {
                printf("ATTENTION : the dim(s) of array %s in file %s.f90 is FULL size. \n", a, f);
            }
        }
    }
}

void slave_if_is_full_size_dim_4d(char *array_name, int array_name_len, char *file_name,
                                  int file_name_len, int ldm_dim1_ub, int ldm_dim1_lb,
                                  int orig_dim1_ub, int orig_dim1_lb, int ldm_dim2_ub,
                                  int ldm_dim2_lb, int orig_dim2_ub, int orig_dim2_lb,
                                  int ldm_dim3_ub, int ldm_dim3_lb, int orig_dim3_ub,
                                  int orig_dim3_lb, int ldm_dim4_ub, int ldm_dim4_lb,
                                  int orig_dim4_ub, int orig_dim4_lb, int is_local)
{
    char *a;
    char *f;
    a = (char *)malloc(array_name_len);
    f = (char *)malloc(file_name_len);
    strncpy(a, array_name, array_name_len);
    strncpy(f, file_name, file_name_len);
    if ((ldm_dim1_ub - ldm_dim1_lb + 1) * (ldm_dim2_ub - ldm_dim2_lb + 1) *
            (ldm_dim3_ub - ldm_dim3_lb + 1) * (ldm_dim4_ub - ldm_dim4_lb + 1) * 8 / 1024 >=
        10) {
        if (is_local) {
            printf(
                "ATTENTION : the array %s is local and is bigger than 10K in file %s.f90 is FULL "
                "size. \n",
                a, f);
        } else {
            if ((ldm_dim1_ub == orig_dim1_ub && ldm_dim1_lb == orig_dim1_lb) ||
                (ldm_dim2_ub == orig_dim2_ub && ldm_dim2_lb == orig_dim2_lb) ||
                (ldm_dim3_ub == orig_dim3_ub && ldm_dim3_lb == orig_dim3_lb) ||
                (ldm_dim4_ub == orig_dim4_ub && ldm_dim4_lb == orig_dim4_lb)) {
                printf(
                    "ATTENTION : the dim(s) of array %s in file %s.f90 is FULL size and is bigger "
                    "than 10k. \n",
                    a, f);
            }
        }
    }
}

void slave_if_is_ldm_overflow_(int ldm_size, char *file_name)
{
    return slave_if_is_ldm_overflow(ldm_size, file_name);
}
void slave_if_is_full_size_dim_1d_(char *array_name, int array_name_len, char *file_name,
                                   int file_name_len, int ldm_dim1_ub, int ldm_dim1_lb,
                                   int orig_dim1_ub, int orig_dim1_lb, int is_local)
{
    return slave_if_is_full_size_dim_1d(array_name, array_name_len, file_name, file_name_len,
                                        ldm_dim1_ub, ldm_dim1_lb, orig_dim1_ub, orig_dim1_lb,
                                        is_local);
}
void slave_if_is_full_size_dim_2d_(char *array_name, int array_name_len, char *file_name,
                                   int file_name_len, int ldm_dim1_ub, int ldm_dim1_lb,
                                   int orig_dim1_ub, int orig_dim1_lb, int ldm_dim2_ub,
                                   int ldm_dim2_lb, int orig_dim2_ub, int orig_dim2_lb,
                                   int is_local)
{
    return slave_if_is_full_size_dim_2d(
        array_name, array_name_len, file_name, file_name_len, ldm_dim1_ub, ldm_dim1_lb,
        orig_dim1_ub, orig_dim1_lb, ldm_dim2_ub, ldm_dim2_lb, orig_dim2_ub, orig_dim2_lb, is_local);
}
void slave_if_is_full_size_dim_3d_(char *array_name, int array_name_len, char *file_name,
                                   int file_name_len, int ldm_dim1_ub, int ldm_dim1_lb,
                                   int orig_dim1_ub, int orig_dim1_lb, int ldm_dim2_ub,
                                   int ldm_dim2_lb, int orig_dim2_ub, int orig_dim2_lb,
                                   int ldm_dim3_ub, int ldm_dim3_lb, int orig_dim3_ub,
                                   int orig_dim3_lb, int is_local)
{
    return slave_if_is_full_size_dim_3d(
        array_name, array_name_len, file_name, file_name_len, ldm_dim1_ub, ldm_dim1_lb,
        orig_dim1_ub, orig_dim1_lb, ldm_dim2_ub, ldm_dim2_lb, orig_dim2_ub, orig_dim2_lb,
        ldm_dim3_ub, ldm_dim3_lb, orig_dim3_ub, orig_dim3_lb, is_local);
}
void slave_if_is_full_size_dim_4d_(char *array_name, int array_name_len, char *file_name,
                                   int file_name_len, int ldm_dim1_ub, int ldm_dim1_lb,
                                   int orig_dim1_ub, int orig_dim1_lb, int ldm_dim2_ub,
                                   int ldm_dim2_lb, int orig_dim2_ub, int orig_dim2_lb,
                                   int ldm_dim3_ub, int ldm_dim3_lb, int orig_dim3_ub,
                                   int orig_dim3_lb, int ldm_dim4_ub, int ldm_dim4_lb,
                                   int orig_dim4_ub, int orig_dim4_lb, int is_local)
{
    return slave_if_is_full_size_dim_4d(
        array_name, array_name_len, file_name, file_name_len, ldm_dim1_ub, ldm_dim1_lb,
        orig_dim1_ub, orig_dim1_lb, ldm_dim2_ub, ldm_dim2_lb, orig_dim2_ub, orig_dim2_lb,
        ldm_dim3_ub, ldm_dim3_lb, orig_dim3_ub, orig_dim3_lb, ldm_dim4_ub, ldm_dim4_lb,
        orig_dim4_ub, orig_dim4_lb, is_local);
}

int slave_acemesh_athread_get_(int mode, void *src, void *dest, int len, void *reply, int mask,
                               int stride, int bsize)
{
    //   if(stride >=0)
    //     athread_dma_iget_stride(dest,src,len,bsize,stride,reply);
    ////   else if(stride==0)
    ////     athread_dma_iget(dest,src,len,reply);
    //   else
    //   {
    //     printf("eror stride=%d\n",stride);
    //     assert(0);
    //   }
    athread_get(mode, src, dest, len, reply, mask, stride, bsize);
    return 0;
}
int slave_acemesh_athread_put_(int mode, void *src, void *dest, int len, void *reply, int stride,
                               int bsize)
{
    //   if(stride > 0)
    //     athread_dma_iput_stride (dest, src, len, bsize, stride, reply);
    //   else if(stride ==0)
    //     athread_dma_iput(dest, src, len, reply);
    //   else
    //   {
    //     printf("eror stride=%d\n",stride);
    //     assert(0);
    //   }
    athread_put(mode, src, dest, len, reply, stride, bsize);
    return 0;
}

int slave_acemesh_athread_get(int mode, void *src, void *dest, int len, void *reply, int mask,
                              int stride, int bsize)
{
    athread_get(mode, src, dest, len, reply, mask, stride, bsize);
    return 0;
}
int slave_acemesh_athread_put(int mode, void *src, void *dest, int len, void *reply, int stride,
                              int bsize)
{
    athread_put(mode, src, dest, len, reply, stride, bsize);
    return 0;
}

void slave_acemesh_memcpy_copyin_towards(char *data, int des_idx, int src_idx, int bytes)
{
// small addr:src_idx,src_idx+1,...,src_idx+bytes - 1
#define COPYIN_GRAIN_SIZE 2048
    char buf[COPYIN_GRAIN_SIZE];

    if (src_idx + bytes - 1 < des_idx) {
        memcpy(&data[des_idx], &data[src_idx], bytes);
    } else if (bytes <= COPYIN_GRAIN_SIZE) {
        memcpy(buf, &data[src_idx], bytes);
        memcpy(&data[des_idx], buf, bytes);
    } else {
        int idx = 0;
        int idx1 = 0;

        while (idx < bytes) {
            int len = COPYIN_GRAIN_SIZE;
            if (idx + len > bytes) {
                len -= (idx + len - bytes);
            }
            idx += len;
            idx1 = bytes - idx;
            memcpy(buf, &data[src_idx + idx1], len);
            memcpy(&data[des_idx + idx1], buf, len);
        }
        if (idx1 != 0) {
            printf("copyin_towards error %d\n", idx1);
        }
    }
}
void slave_acemesh_memcpy_copyout_afterwards(char *data, int des_idx, int src_idx, int bytes)
{
// small address: des_idx,des_idx+1,...,des_idx+bytes - 1
// big addr:src_idx,src_idx+1,...,src_idx+bytes - 1
//
#define COPYIN_GRAIN_SIZE 2048
    char buf[COPYIN_GRAIN_SIZE];

    if (des_idx + bytes - 1 < src_idx) {
        memcpy(&data[des_idx], &data[src_idx], bytes);
    } else if (bytes <= COPYIN_GRAIN_SIZE) {
        memcpy(buf, &data[src_idx], bytes);
        memcpy(&data[des_idx], buf, bytes);
    } else {
        int idx = 0;
        while (idx < bytes) {
            int len = COPYIN_GRAIN_SIZE;
            if (idx + len > bytes) {
                len -= (idx + len - bytes);
            }

            memcpy(buf, &data[src_idx + idx], len);
            memcpy(&data[des_idx + idx], buf, len);
            idx += len;
        }
    }
}

void slave_acemesh_reshape_copyin2d(void *data, int d1, int t1, int d2, int t2, int e_type_size,
                                    int stride_no)
{
    int i;
    char *pdata = (char *)data;
    int sd1 = d1 * e_type_size;
    int st1 = t1 * e_type_size;
    for (i = t2 - 1; i > 0; i--) {
        /*memcpy(&pdata[i*sd1],
                 &pdata[i*st1],
                 st1);*/
        slave_acemesh_memcpy_copyin_towards(pdata, i * sd1, i * st1, st1);
    }
}

// void slave_acemesh_reshape_copyin2d(void *data,int d1,int t1,int d2,int t2,int e_type_size, int
// stride_no) {
//     int i,j;
//     char *pdata=(char *)data;
//     for(i=d2-1;i>=0;i--)
//         for(j=d1-1;j>=0;j--)
//             memcpy(&pdata[(i*d1+j)*e_type_size],&pdata[(i*t1+j)*e_type_size],e_type_size);
// }

void slave_acemesh_reshape_copyout2d(void *data, int d1, int t1, int d2, int t2, int e_type_size,
                                     int stride_no)
{
    int i;
    char *pdata = (char *)data;
    int sd1 = d1 * e_type_size;
    int st1 = t1 * e_type_size;

    for (i = 1; i <= t2 - 1; i++) {
        slave_acemesh_memcpy_copyout_afterwards(pdata, i * st1, i * sd1, st1);
    }
}

//
// void slave_acemesh_reshape_copyout2d(void *data,int d1,int t1,int d2,int t2,int e_type_size, int
// stride_no) {
//    int i,j;
//    char *pdata=(char *)data;
//    for(i=0;i<=t2-1;i++)
//        for(j=0;j<=t1-1;j++)
//            memcpy(&pdata[(i*t1+j)*e_type_size],&pdata[(i*d1+j)*e_type_size],e_type_size);
//}

/*from the 3d c array(t3,t2,t1) to the  3d c array(d3,d2,d1) */
/* the corresponding fortran array is (t1,t2,t3) and (d1,d2,d3) respectively */
/* in fact, expand data */
// stride_no starts from 0, it must be >= 1 && <= dim_num - 1
// so,in this case, stride_no is 1 or 2

void slave_acemesh_reshape_copyin3d(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                    int e_type_size, int stride_no)
{
    int i, j;
    char *pdata = (char *)data;
    int sd1 = d1 * e_type_size;
    int sd2 = d2 * sd1;
    int st1 = t1 * e_type_size;
    int st2 = t2 * sd1;

    if (stride_no == 1) {
        for (j = t3 - 1; j >= 0; j--) {
            for (i = t2 - 1; i > 0; i--) {
                slave_acemesh_memcpy_copyin_towards(pdata, j * sd2 + i * sd1, j * sd2 + i * st1,
                                                    st1);
            }
        }
    } else if (stride_no == 2) {
        for (j = t3 - 1; j > 0; j--) {
            slave_acemesh_memcpy_copyin_towards(pdata, j * sd2, j * st2, st2);
        }
    }
}

//
// void slave_acemesh_reshape_copyin3d(void *data,int d1,int t1,int d2,int t2,int d3,int t3,int
// e_type_size, int stride_no) {
//        int i,j,k;
//        char *pdata=(char *)data;
//
//        int dim_size[3];
//        int tile_size[3];
//        int stride[3];
//        int stride_dim;
//        int len,offset;
//
// #ifdef TEMP_RESHAPE
//        char * dest_addr=NULL;
//        char * src_tail_addr=NULL;
// #endif
//
//        dim_size[0] = d1;
//        dim_size[1] = d2;
//        dim_size[2] = d3;
//        tile_size[0] = t1;
//        tile_size[1] = t2;
//        tile_size[2] = t3;
//
//        for (i=2; i > 0; i--) {
//            stride[i] = 1;
//            for (j = i-1; j >= 0; j--) {
//                if (i > stride_no) {
//                    stride_dim = dim_size[j];
//                    }
//                    else {
//                        stride_dim = tile_size[j];
//                    }
//
//                    stride[i] *= stride_dim;
//            }
//    }
//    stride[0] = 1;
//
//    len=e_type_size*d1;
//    offset=d2*d1;
//    for(i=d3-1;i>=0;i--)
//        for(j=d2-1;j>=0;j--)
//        {
// #ifdef TEMP_RESHAPE
//           dest_addr=&pdata[(i*(offset)+j*d1)*e_type_size];
//           src_addr=&pdata[(i*stride[2]+j*stride[1])*e_type_size];
//           src_tail_addr=src_addr+len;
//           if(dest_addr<src_tail_addr)
//           {
//               char* reshape_buff=ldm_malloc();
//               memcpy(reshape_buff,src_addr,len);
//               memcpy(dest_addr,reshape_buff);
//               ldm_free();
//           }
//
// #else
//            memcpy(&pdata[(i*(offset)+j*d1)*e_type_size],
//                &pdata[(i*stride[2]+j*stride[1])*e_type_size],
//                len);
// #endif
//        }
//}

/*from the 3d c array(d3,d2,d1) to the  3d c array(t3,t3,t1) */
/* the corresponding fortran array is (t1,t2,t3) and (d1,d2,d3) respectively */
/* in fact, compress data first before output from ldm to mm */
void slave_acemesh_reshape_copyout3d(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                     int e_type_size, int stride_no)
{
    int i, j;
    char *pdata = (char *)data;
    int sd1 = d1 * e_type_size;
    int sd2 = d2 * sd1;
    int st1 = t1 * e_type_size;
    int st2 = t2 * sd1;

    if (stride_no == 1) {
        for (j = 0; j < t3; j++) {
            for (i = 1; i < t2; i++) {
                slave_acemesh_memcpy_copyout_afterwards(pdata, j * sd2 + i * st1, j * sd2 + i * sd1,
                                                        st1);
            }
        }
    } else if (stride_no == 2) {
        for (j = 1; j < t3; j++) {
            slave_acemesh_memcpy_copyout_afterwards(pdata, j * st2, j * sd2, st2);
        }
    }
}
//
// void slave_acemesh_reshape_copyout3d(void *data,int d1,int t1,int d2,int t2,int d3,int t3,int
// e_type_size, int stride_no) {
//        int i,j,k;
//        char *pdata=(char *)data;
//        int dim_size[3];
//        int tile_size[3];
//        int stride[3];
//        int stride_dim;
//
//        dim_size[0] = d1;
//        dim_size[1] = d2;
//        dim_size[2] = d3;
//        tile_size[0] = t1;
//        tile_size[1] = t2;
//        tile_size[2] = t3;
//        for (i=2; i > 0; i--) {
//            stride[i] = 1;
//            for (j = i-1; j >= 0; j--) {
//                 if (i > stride_no) {
//                     stride_dim = dim_size[j];
//                 }
//                 else {
//                     stride_dim = tile_size[j];
//                 }
//
//                 stride[i] *= stride_dim;
//            }
//        }
//        stride[0] = 1;
//        for(i=0;i<=t3-1;i++)
//            for(j=0;j<=t2-1;j++)
//                for(k=0;k<=t1-1;k++)
//                    memcpy(&pdata[(i*stride[2]+
//                        j*stride[1]+k)*e_type_size],
//                        &pdata[(i*(d2*d1)+j*d1+k)*e_type_size],
//                        e_type_size);
//
//}

void slave_acemesh_reshape_copyin4d(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                    int d4, int t4, int e_type_size, int stride_no)
{
    int i, j, k;
    char *pdata = (char *)data;
    int sd1 = d1 * e_type_size;
    int sd2 = d2 * sd1;
    int sd3 = d3 * sd2;
    int st1 = t1 * e_type_size;
    int st2 = t2 * sd1;
    int st3 = t3 * sd2;

    if (stride_no == 1) {
        for (k = t4 - 1; k >= 0; k--) {
            for (j = t3 - 1; j >= 0; j--) {
                for (i = t2 - 1; i > 0; i--) {
                    slave_acemesh_memcpy_copyin_towards(pdata, k * sd3 + j * sd2 + i * sd1,
                                                        k * sd3 + j * sd2 + i * st1, st1);
                }
            }
        }
    } else if (stride_no == 2) {
        for (k = t4 - 1; k >= 0; k--) {
            for (j = t3 - 1; j > 0; j--) {
                slave_acemesh_memcpy_copyin_towards(pdata, k * sd3 + j * sd2, k * sd3 + j * st2,
                                                    st2);
            }
        }
    } else if (stride_no == 3) {
        for (k = t4 - 1; k > 0; k--) {
            slave_acemesh_memcpy_copyin_towards(pdata, k * sd3, k * st3, st3);
        }
    }
}

//
// void slave_acemesh_reshape_copyin4d(void *data,int d1,int t1,int d2,int t2,int d3,int t3,int
// d4,int t4,int e_type_size, int stride_no) {
//        int i,j,k,l;
//        char *pdata=(char *)data;
//        int dim_size[4];
//        int tile_size[4];
//        int stride[4];
//        int stride_dim;
//
//
//        dim_size[0] = d1;
//        dim_size[1] = d2;
//        dim_size[2] = d3;
//        dim_size[3] = d4;
//        tile_size[0] = t1;
//        tile_size[1] = t2;
//        tile_size[2] = t3;
//        tile_size[3] = t4;
//        for (i=3; i > 0; i--) {
//            stride[i] = 1;
//            for (j = i-1; j >= 0; j--) {
//                 if (i > stride_no) {
//                     stride_dim = dim_size[j];
//                 }
//                 else {
//                     stride_dim = tile_size[j];
//                 }
//                 stride[i] *= stride_dim;
//             }
//        }
//        stride[0] = 1;
//
//        for(i=d4-1;i>=0;i--)
//            for(j=d3-1;j>=0;j--)
//                for(k=d2-1;k>=0;k--)
//                    for(l=d1-1;l>=0;l--)
//                        memcpy(&pdata[(i*(d3*d2*d1)+j*(d2*d1)+k*d1+l)*e_type_size],
//                            &pdata[(i*stride[3]+
//                            j*stride[2]+
//                            k*stride[1]+l)*e_type_size],
//                            e_type_size);
//}

void slave_acemesh_reshape_copyout4d(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                     int d4, int t4, int e_type_size, int stride_no)
{
    int i, j, k;
    char *pdata = (char *)data;
    int sd1 = d1 * e_type_size;
    int sd2 = d2 * sd1;
    int sd3 = d3 * sd2;
    int st1 = t1 * e_type_size;
    int st2 = t2 * sd1;
    int st3 = t3 * sd2;

    if (stride_no == 1) {
        for (k = 0; k < t4; k++) {
            for (j = 0; j < t3; j++) {
                for (i = 1; i < t2; i++) {
                    slave_acemesh_memcpy_copyout_afterwards(pdata, k * sd3 + j * sd2 + i * st1,
                                                            k * sd3 + j * sd2 + i * sd1, st1);
                }
            }
        }
    } else if (stride_no == 2) {
        for (k = 0; k < t4; k++) {
            for (j = 1; j < t3; j++) {
                slave_acemesh_memcpy_copyout_afterwards(pdata, k * sd3 + j * st2, k * sd3 + j * sd2,
                                                        st2);
            }
        }
    } else if (stride_no == 3) {
        for (k = 1; k < t4; k++) {
            slave_acemesh_memcpy_copyout_afterwards(pdata, k * st3, k * sd3, st3);
        }
    }
}

//
// void slave_acemesh_reshape_copyout4d(void *data,int d1,int t1,int d2,int t2,int d3,int t3,int
// d4,int t4,int e_type_size, int stride_no) {
//        int i,j,k,l;
//        char *pdata=(char *)data;
//        int dim_size[4];
//        int tile_size[4];
//        int stride[4];
//        int stride_dim;
//
//
//        dim_size[0] = d1;
//        dim_size[1] = d2;
//        dim_size[2] = d3;
//        dim_size[3] = d4;
//        tile_size[0] = t1;
//        tile_size[1] = t2;
//        tile_size[2] = t3;
//        tile_size[3] = t4;
//
//        for (i=3; i > 0; i--) {
//            stride[i] = 1;
//            for (j = i-1; j >= 0; j--) {
//                if (i > stride_no) {
//                    stride_dim = dim_size[j];
//                }
//                else {
//                    stride_dim = tile_size[j];
//                }
//
//                stride[i] *= stride_dim;
//            }
//        }
//        stride[0] = 1;
//
//        for(i=0;i<=t4-1;i++)
//            for(j=0;j<=t3-1;j++)
//                for(k=0;k<=t2-1;k++)
//                    for(l=0;l<=t1-1;l++)
//                        memcpy(&pdata[(i*stride[3]+
//                            j*stride[2]+
//                            k*stride[1]+l)*e_type_size],
//                            &pdata[(i*(d3*d2*d1)+j*(d2*d1)+k*d1+l)*e_type_size],
//                           e_type_size);
//}

void slave_acemesh_reshape_copyin5d(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                    int d4, int t4, int d5, int t5, int e_type_size, int stride_no)
{
    int i, j, k, m;
    char *pdata = (char *)data;
    int sd1 = d1 * e_type_size;
    int sd2 = d2 * sd1;
    int sd3 = d3 * sd2;
    int sd4 = d4 * sd3;
    int st1 = t1 * e_type_size;
    int st2 = t2 * sd1;
    int st3 = t3 * sd2;
    int st4 = t4 * sd3;

    if (stride_no == 1) {
        for (m = t5 - 1; m >= 0; m--) {
            for (k = t4 - 1; k >= 0; k--) {
                for (j = t3 - 1; j >= 0; j--) {
                    for (i = t2 - 1; i > 0; i--) {
                        slave_acemesh_memcpy_copyin_towards(
                            pdata, m * sd4 + k * sd3 + j * sd2 + i * sd1,
                            m * sd4 + k * sd3 + j * sd2 + i * st1, st1);
                    }
                }
            }
        }
    } else if (stride_no == 2) {
        for (m = t5 - 1; m >= 0; m--) {
            for (k = t4 - 1; k >= 0; k--) {
                for (j = t3 - 1; j > 0; j--) {
                    slave_acemesh_memcpy_copyin_towards(pdata, m * sd4 + k * sd3 + j * sd2,
                                                        m * sd4 + k * sd3 + j * st2, st2);
                }
            }
        }
    } else if (stride_no == 3) {
        for (m = t5 - 1; m >= 0; m--) {
            for (k = t4 - 1; k > 0; k--) {
                slave_acemesh_memcpy_copyin_towards(pdata, m * sd4 + k * sd3, m * sd4 + k * st3,
                                                    st3);
            }
        }
    } else if (stride_no == 4) {
        for (m = t5 - 1; m > 0; m--) {
            slave_acemesh_memcpy_copyin_towards(pdata, m * sd4, m * st4, st4);
        }
    }
}

//
// void slave_acemesh_reshape_copyin5d(void *data,int d1,int t1,int d2,int t2,int d3,int t3,int
// d4,int t4,int d5,int t5,int e_type_size, int stride_no) {
//        int h,i,j,k,l;
//        char *pdata=(char *)data;
//        int dim_size[5];
//        int tile_size[5];
//        int stride[5];
//        int stride_dim;
//
//
//        dim_size[0] = d1;
//        dim_size[1] = d2;
//        dim_size[2] = d3;
//        dim_size[3] = d4;
//        dim_size[4] = d5;
//        tile_size[0] = t1;
//        tile_size[1] = t2;
//        tile_size[2] = t3;
//        tile_size[3] = t4;
//        tile_size[4] = t5;
//
//        for (i=4; i > 0; i--) {
//            stride[i] = 1;
//            for (j = i-1; j >= 0; j--) {
//                if (i > stride_no) {
//                    stride_dim = dim_size[j];
//                }
//                else {
//                    stride_dim = tile_size[j];
//                }
//
//                stride[i] *= stride_dim;
//            }
//        }
//        stride[0] = 1;
//
//        for(h=d5-1;h>=0;h--)
//            for(i=d4-1;i>=0;i--)
//                for(j=d3-1;j>=0;j--)
//                    for(k=d2-1;k>=0;k--)
//                        for(l=d1-1;l>=0;l--)
//                            memcpy(&pdata[(h*(d4*d3*d2*d1)+i*(d3*d2*d1)+j*(d2*d1)+k*d1+l)*e_type_size],
//                                &pdata[(h*stride[4]+
//                                i*stride[3]+
//                                j*stride[2]+
//                                k*stride[1]+l)*e_type_size],
//                                e_type_size);
//}

void slave_acemesh_reshape_copyout5d(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                     int d4, int t4, int d5, int t5, int e_type_size, int stride_no)
{
    int i, j, k, m;
    char *pdata = (char *)data;
    int sd1 = d1 * e_type_size;
    int sd2 = d2 * sd1;
    int sd3 = d3 * sd2;
    int sd4 = d4 * sd3;
    int st1 = t1 * e_type_size;
    int st2 = t2 * sd1;
    int st3 = t3 * sd2;
    int st4 = t4 * sd3;

    if (stride_no == 1) {
        for (m = 0; m < t5; m++) {
            for (k = 0; k < t4; k++) {
                for (j = 0; j < t3; j++) {
                    for (i = 1; i < t2; i++) {
                        slave_acemesh_memcpy_copyout_afterwards(
                            pdata, m * sd4 + k * sd3 + j * sd2 + i * st1,
                            m * sd4 + k * sd3 + j * sd2 + i * sd1, st1);
                    }
                }
            }
        }
    } else if (stride_no == 2) {
        for (m = 0; m < t5; m++) {
            for (k = 0; k < t4; k++) {
                for (j = 1; j < t3; j++) {
                    slave_acemesh_memcpy_copyout_afterwards(pdata, m * sd4 + k * sd3 + j * st2,
                                                            m * sd4 + k * sd3 + j * sd2, st2);
                }
            }
        }
    } else if (stride_no == 3) {
        for (m = 0; m < t5; m++) {
            for (k = 1; k < t4; k++) {
                slave_acemesh_memcpy_copyout_afterwards(pdata, m * sd4 + k * st3, m * sd4 + k * sd3,
                                                        st3);
            }
        }
    } else if (stride_no == 4) {
        for (m = 1; m < t5; m++) {
            slave_acemesh_memcpy_copyout_afterwards(pdata, m * st4, m * sd4, st4);
        }
    }
}

//
// void slave_acemesh_reshape_copyout5d(void *data,int d1,int t1,int d2,int t2,int d3,int t3,int
// d4,int t4,int d5,int t5,int e_type_size, int stride_no) {
//        int h,i,j,k,l;
//        char *pdata=(char *)data;
//        int dim_size[5];
//        int tile_size[5];
//        int stride[5];
//        int stride_dim;
//
//
//        dim_size[0] = d1;
//        dim_size[1] = d2;
//        dim_size[2] = d3;
//        dim_size[3] = d4;
//        dim_size[4] = d5;
//        tile_size[0] = t1;
//        tile_size[1] = t2;
//        tile_size[2] = t3;
//        tile_size[3] = t4;
//        tile_size[4] = t5;
//        for (i=4; i > 0; i--) {
//            stride[i] = 1;
//            for (j = i-1; j >= 0; j--) {
//                if (i > stride_no) {
//                    stride_dim = dim_size[j];
//                }
//                else {
//                    stride_dim = tile_size[j];
//                }
//
//                    stride[i] *= stride_dim;
//                }
//        }
//        stride[0] = 1;
//
//        for(h=0;h<=t5-1;h++)
//            for(i=0;i<=t4-1;i++)
//                for(j=0;j<=t3-1;j++)
//                    for(k=0;k<=t2-1;k++)
//                        for(l=0;l<=t1-1;l++)
//                            memcpy(&pdata[(h*stride[4]+
//                                i*stride[3]+
//                                j*stride[2]+
//                                k*stride[1]+l)*e_type_size],
//                                &pdata[(h*(d4*d3*d2*d1)+i*(d3*d2*d1)+j*(d2*d1)+k*d1+l)*e_type_size],
//                                e_type_size);
//}
//

void slave_acemesh_reshape_copyin6d(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                    int d4, int t4, int d5, int t5, int d6, int t6, int e_type_size,
                                    int stride_no)
{
    int i, j, k, m, n;
    char *pdata = (char *)data;
    int sd1 = d1 * e_type_size;
    int sd2 = d2 * sd1;
    int sd3 = d3 * sd2;
    int sd4 = d4 * sd3;
    int sd5 = d5 * sd4;
    int st1 = t1 * e_type_size;
    int st2 = t2 * sd1;
    int st3 = t3 * sd2;
    int st4 = t4 * sd3;
    int st5 = t5 * sd4;

    if (stride_no == 1) {
        for (n = t6 - 1; n >= 0; n--) {
            for (m = t5 - 1; m >= 0; m--) {
                for (k = t4 - 1; k >= 0; k--) {
                    for (j = t3 - 1; j >= 0; j--) {
                        for (i = t2 - 1; i > 0; i--) {
                            slave_acemesh_memcpy_copyin_towards(
                                pdata, n * sd5 + m * sd4 + k * sd3 + j * sd2 + i * sd1,
                                n * sd5 + m * sd4 + k * sd3 + j * sd2 + i * st1, st1);
                        }
                    }
                }
            }
        }
    } else if (stride_no == 2) {
        for (n = t6 - 1; n >= 0; n--) {
            for (m = t5 - 1; m >= 0; m--) {
                for (k = t4 - 1; k >= 0; k--) {
                    for (j = t3 - 1; j > 0; j--) {
                        slave_acemesh_memcpy_copyin_towards(
                            pdata, n * sd5 + m * sd4 + k * sd3 + j * sd2,
                            n * sd5 + m * sd4 + k * sd3 + j * st2, st2);
                    }
                }
            }
        }
    } else if (stride_no == 3) {
        for (n = t6 - 1; n >= 0; n--) {
            for (m = t5 - 1; m >= 0; m--) {
                for (k = t4 - 1; k > 0; k--) {
                    slave_acemesh_memcpy_copyin_towards(pdata, n * sd5 + m * sd4 + k * sd3,
                                                        n * sd5 + m * sd4 + k * st3, st3);
                }
            }
        }
    } else if (stride_no == 4) {
        for (n = t6 - 1; n >= 0; n--) {
            for (m = t5 - 1; m > 0; m--) {
                slave_acemesh_memcpy_copyin_towards(pdata, n * sd5 + m * sd4, n * sd5 + m * st4,
                                                    st4);
            }
        }
    } else if (stride_no == 5) {
        for (n = t6 - 1; n > 0; n--) {
            slave_acemesh_memcpy_copyin_towards(pdata, n * sd5, n * st5, st5);
        }
    }
}

//
// void slave_acemesh_reshape_copyin6d(void *data,int d1,int t1,int d2,int t2,int d3,int t3,int
// d4,int t4,int d5,int t5,int d6,int t6,int e_type_size, int stride_no) {
//        int g,h,i,j,k,l;
//        char *pdata=(char *)data;
//        int dim_size[6];
//        int tile_size[6];
//        int stride[6];
//        int stride_dim;
//
//
//        dim_size[0] = d1;
//        dim_size[1] = d2;
//        dim_size[2] = d3;
//        dim_size[3] = d4;
//        dim_size[4] = d5;
//        dim_size[5] = d6;
//        tile_size[0] = t1;
//        tile_size[1] = t2;
//        tile_size[2] = t3;
//        tile_size[3] = t4;
//        tile_size[4] = t5;
//        tile_size[5] = t6;
//        for (i=5; i > 0; i--) {
//            stride[i] = 1;
//            for (j = i-1; j >= 0; j--) {
//                if (i > stride_no) {
//                    stride_dim = dim_size[j];
//                }
//                else {
//                    stride_dim = tile_size[j];
//                }
//
//                stride[i] *= stride_dim;
//            }
//        }
//        stride[0] = 1;
//
//        for(g=d6-1;g>=0;g--)
//            for(h=d5-1;h>=0;h--)
//                for(i=d4-1;i>=0;i--)
//                    for(j=d3-1;j>=0;j--)
//                        for(k=d2-1;k>=0;k--)
//                            for(l=d1-1;l>=0;l--)
//                                memcpy(&pdata[(g*(d5*d4*d3*d2*d1)+h*(d4*d3*d2*d1)+i*(d3*d2*d1)+j*(d2*d1)+k*d1+l)*e_type_size],
//                                    &pdata[(g*stride[5]+
//                                    h*stride[4]+
//                                    i*stride[3]+
//                                    j*stride[2]+
//                                    k*stride[1]+l)*e_type_size],
//                                    e_type_size);
//}
//

void slave_acemesh_reshape_copyout6d(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                     int d4, int t4, int d5, int t5, int d6, int t6,
                                     int e_type_size, int stride_no)
{
    int i, j, k, m, n;
    char *pdata = (char *)data;
    int sd1 = d1 * e_type_size;
    int sd2 = d2 * sd1;
    int sd3 = d3 * sd2;
    int sd4 = d4 * sd3;
    int sd5 = d5 * sd4;
    int sd6 = d5 * sd4;
    int st1 = t1 * e_type_size;
    int st2 = t2 * sd1;
    int st3 = t3 * sd2;
    int st4 = t4 * sd3;
    int st5 = t5 * sd4;

    if (stride_no == 1) {
        for (n = 0; n < t6; n++) {
            for (m = 0; m < t5; m++) {
                for (k = 0; k < t4; k++) {
                    for (j = 0; j < t3; j++) {
                        for (i = 1; i < t2; i++) {
                            slave_acemesh_memcpy_copyout_afterwards(
                                pdata, n * sd5 + m * sd4 + k * sd3 + j * sd2 + i * st1,
                                n * sd5 + m * sd4 + k * sd3 + j * sd2 + i * sd1, st1);
                        }
                    }
                }
            }
        }
    } else if (stride_no == 2) {
        for (n = 0; n < t6; n++) {
            for (m = 0; m < t5; m++) {
                for (k = 0; k < t4; k++) {
                    for (j = 1; j < t3; j++) {
                        slave_acemesh_memcpy_copyout_afterwards(
                            pdata, n * sd5 + m * sd4 + k * sd3 + j * st2,
                            n * sd5 + m * sd4 + k * sd3 + j * sd2, st2);
                    }
                }
            }
        }
    } else if (stride_no == 3) {
        for (n = 0; n < t6; n++) {
            for (m = 0; m < t5; m++) {
                for (k = 1; k < t4; k++) {
                    slave_acemesh_memcpy_copyout_afterwards(pdata, n * sd5 + m * sd4 + k * st3,
                                                            n * sd5 + m * sd4 + k * sd3, st3);
                }
            }
        }
    } else if (stride_no == 4) {
        for (n = 0; n < t6; n++) {
            for (m = 1; m < t5; m++) {
                slave_acemesh_memcpy_copyout_afterwards(pdata, n * sd5 + m * st4, n * sd5 + m * sd4,
                                                        st4);
            }
        }
    } else if (stride_no == 5) {
        for (n = 1; n < t6; n++) {
            slave_acemesh_memcpy_copyout_afterwards(pdata, n * st5, n * sd5, st5);
        }
    }
}

//
//
// void slave_acemesh_reshape_copyout6d(void *data,int d1,int t1,int d2,int t2,int d3,int t3,int
// d4,int t4,int d5,int t5,int d6,int t6,int e_type_size, int stride_no) {
//        int g,h,i,j,k,l;
//        char *pdata=(char *)data;
//        int dim_size[6];
//        int tile_size[6];
//        int stride[6];
//        int stride_dim;
//
//        dim_size[0] = d1;
//        dim_size[1] = d2;
//        dim_size[2] = d3;
//        dim_size[3] = d4;
//        dim_size[4] = d5;
//        dim_size[5] = d6;
//        tile_size[0] = t1;
//        tile_size[1] = t2;
//        tile_size[2] = t3;
//        tile_size[3] = t4;
//        tile_size[4] = t5;
//        tile_size[5] = t6;
//
//        for (i=5; i > 0; i--) {
//            stride[i] = 1;
//            for (j = i-1; j >= 0; j--) {
//                if (i > stride_no) {
//                    stride_dim = dim_size[j];
//                }
//                else {
//                    stride_dim = tile_size[j];
//                }
//
//                stride[i] *= stride_dim;
//            }
//        }
//        stride[0] = 1;
//
//        for(g=0;g<=t6-1;g++)
//            for(h=0;h<=t5-1;h++)
//                for(i=0;i<=t4-1;i++)
//                    for(j=0;j<=t3-1;j++)
//                        for(k=0;k<=t2-1;k++)
//                            for(l=0;l<=t1-1;l++)
//                                memcpy(&pdata[(g*stride[5]+
//                                    h*stride[4]+
//                                    i*stride[3]+
//                                    j*stride[2]+
//                                    k*stride[1]+l)*e_type_size],
//                                    &pdata[(g*(d5*d4*d3*d2*d1)+h*(d4*d3*d2*d1)+i*(d3*d2*d1)+j*(d2*d1)+k*d1+l)*e_type_size],
//                                    e_type_size);
//}
//
//

void slave_acemesh_reshape_copyin2d_(void *data, int d1, int t1, int d2, int t2, int e_type_size,
                                     int stride_no)
{
    slave_acemesh_reshape_copyin2d(data, d1, t1, d2, t2, e_type_size, stride_no);
}

void slave_acemesh_reshape_copyout2d_(void *data, int d1, int t1, int d2, int t2, int e_type_size,
                                      int stride_no)
{
    slave_acemesh_reshape_copyout2d(data, d1, t1, d2, t2, e_type_size, stride_no);
}

void slave_acemesh_reshape_copyin3d_(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                     int e_type_size, int stride_no)
{
    slave_acemesh_reshape_copyin3d(data, d1, t1, d2, t2, d3, t3, e_type_size, stride_no);
}
void slave_acemesh_reshape_copyout3d_(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                      int e_type_size, int stride_no)
{
    slave_acemesh_reshape_copyout3d(data, d1, t1, d2, t2, d3, t3, e_type_size, stride_no);
}
void slave_acemesh_reshape_copyin4d_(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                     int d4, int t4, int e_type_size, int stride_no)
{
    slave_acemesh_reshape_copyin4d(data, d1, t1, d2, t2, d3, t3, d4, t4, e_type_size, stride_no);
}
void slave_acemesh_reshape_copyout4d_(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                      int d4, int t4, int e_type_size, int stride_no)
{
    slave_acemesh_reshape_copyout4d(data, d1, t1, d2, t2, d3, t3, d4, t4, e_type_size, stride_no);
}
void slave_acemesh_reshape_copyin5d_(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                     int d4, int t4, int d5, int t5, int e_type_size, int stride_no)
{
    slave_acemesh_reshape_copyin5d(data, d1, t1, d2, t2, d3, t3, d4, t4, d5, t5, e_type_size,
                                   stride_no);
}
void slave_acemesh_reshape_copyout5d_(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                      int d4, int t4, int d5, int t5, int e_type_size,
                                      int stride_no)
{
    slave_acemesh_reshape_copyout5d(data, d1, t1, d2, t2, d3, t3, d4, t4, d5, t5, e_type_size,
                                    stride_no);
}
void slave_acemesh_reshape_copyin6d_(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                     int d4, int t4, int d5, int t5, int d6, int t6,
                                     int e_type_size, int stride_no)
{
    slave_acemesh_reshape_copyin6d(data, d1, t1, d2, t2, d3, t3, d4, t4, d5, t5, d6, t6,
                                   e_type_size, stride_no);
}
void slave_acemesh_reshape_copyout6d_(void *data, int d1, int t1, int d2, int t2, int d3, int t3,
                                      int d4, int t4, int d5, int t5, int d6, int t6,
                                      int e_type_size, int stride_no)
{
    slave_acemesh_reshape_copyout6d(data, d1, t1, d2, t2, d3, t3, d4, t4, d5, t5, d6, t6,
                                    e_type_size, stride_no);
}

#ifndef COPY_OLD
void acemesh_print_dma_total_bytes(char *slave_func_name, int dma_total_bytes)
{
    if (dma_total_bytes / 1024 > 100) {
        //      printf("%s occupied %d kb ldm!\n", slave_func_name,dma_total_bytes/1024);
    }
}
void acemesh_print_dma_total_bytes_(char *slave_func_name, int dma_total_bytes)
{
    acemesh_print_dma_total_bytes(slave_func_name, dma_total_bytes);
}
#endif

/*copyin and copyout*/
void slave_acemesh_copyin1d(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                            int c1_lb, int c1_ub,
#ifdef COPY_OLD
                            int e_type_size, int *reply, int *counter)
#else
                            int e_type_size, int *reply, int *counter, int *dma_bytes)
#endif
{
    c1_lb = (c1_lb < d1_lb) ? d1_lb : c1_lb;
    c1_ub = (c1_ub > d1_ub) ? d1_ub : c1_ub;
#ifdef ACEMESH_SCHEDULER_PROFILING
#ifndef COPY_OLD
    *dma_bytes += (t1_ub - t1_lb + 1) * e_type_size;
#endif
#endif

    int nSrcOff = c1_lb - d1_lb;
    nSrcOff *= e_type_size;
    char *psrc = (char *)src;
    psrc += nSrcOff;
    char *pdest = (char *)dest;

    int len = (c1_ub - c1_lb + 1) * e_type_size;
    slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, 0, 0);

    int counter_val = *counter;
    *counter = ++counter_val;
}
void slave_acemesh_copyout1d(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub,
#ifdef COPY_OLD
                             int e_type_size, int *reply, int *counter)
#else
                             int e_type_size, int *reply, int *counter, int *dma_bytes)
#endif
{
    c1_lb = (c1_lb < d1_lb) ? d1_lb : c1_lb;
    c1_ub = (c1_ub > d1_ub) ? d1_ub : c1_ub;

#ifdef ACEMESH_SCHEDULER_PROFILING
#ifndef COPY_OLD
    *dma_bytes += (t1_ub - t1_lb + 1) * e_type_size;
#endif
#endif

    int nDestOff = c1_lb - d1_lb;
    nDestOff *= e_type_size;
    char *psrc = (char *)src;

    char *pdest = (char *)dest;
    pdest += nDestOff;

    int len = (c1_ub - c1_lb + 1) * e_type_size;

    slave_acemesh_athread_put(0, psrc, pdest, len, reply, 0, 0);
    int counter_val = *counter;
    *counter = ++counter_val;
}
void slave_acemesh_copyin2d(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                            int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                            int c2_lb, int c2_ub,
#ifdef COPY_OLD
                            int e_type_size, int *reply, int *counter)
#else
                            int e_type_size, int *reply, int *counter, int *dma_bytes)
#endif
{
    c1_lb = (c1_lb < d1_lb) ? d1_lb : c1_lb;
    c1_ub = (c1_ub > d1_ub) ? d1_ub : c1_ub;

    c2_lb = (c2_lb < d2_lb) ? d2_lb : c2_lb;
    c2_ub = (c2_ub > d2_ub) ? d2_ub : c2_ub;

    int stride_flag = 0;
    int stride_no = 1;

    int dm0 = d1_ub - d1_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;

#ifdef ACEMESH_SCHEDULER_PROFILING
#ifndef COPY_OLD
    *dma_bytes += tm0 * tm1 * e_type_size;
#endif
#endif

    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    }

    char *psrc = (char *)src;
    int nSrcOff = (c2_lb - d2_lb) * dm0 + (c1_lb - d1_lb);
    nSrcOff *= e_type_size;
    psrc += nSrcOff;

    char *pdest = (char *)dest;
    if (stride_no == 0) {
        int len = cm1 * cm0;
        len *= e_type_size;

        int stride = dm0 - cm0;
        stride *= e_type_size;

        int bsize = cm0;
        bsize *= e_type_size;

        slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);

    } else {
        int len = cm1 * dm0;
        len *= e_type_size;

        slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, 0, 0);
    }

    int counter_val = *counter;
    *counter = ++counter_val;
}
void slave_acemesh_copyout2d(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub,
#ifdef COPY_OLD
                             int e_type_size, int *reply, int *counter)
#else
                             int e_type_size, int *reply, int *counter, int *dma_bytes)
#endif
{
    c1_lb = (c1_lb < d1_lb) ? d1_lb : c1_lb;
    c1_ub = (c1_ub > d1_ub) ? d1_ub : c1_ub;

    c2_lb = (c2_lb < d2_lb) ? d2_lb : c2_lb;
    c2_ub = (c2_ub > d2_ub) ? d2_ub : c2_ub;

    int stride_flag = 0;
    int stride_no = 1;
    int reshape_flag = 0;

    int dm0 = d1_ub - d1_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;

#ifdef ACEMESH_SCHEDULER_PROFILING
#ifndef COPY_OLD
    *dma_bytes += tm0 * tm1 * e_type_size;
#endif
#endif

    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    }

    if (tm0 != cm0) {
        reshape_flag = 1;
    }

    if (reshape_flag == 1) {
        if (stride_no == 1) {
            stride_no = 0;
        }
    }

    char *psrc = (char *)src;

    char *pdest = (char *)dest;
    int nDestOff = (c2_lb - d2_lb) * dm0 + (c1_lb - d1_lb);
    nDestOff *= e_type_size;
    pdest += nDestOff;

    if (stride_no == 0) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout2d(psrc, tm0, cm0, tm1, cm1, e_type_size, 1);
        }

        int len = cm1 * cm0;
        len *= e_type_size;

        int stride = dm0 - cm0;
        stride *= e_type_size;

        int bsize = cm0;
        bsize *= e_type_size;

        slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);
    } else {
        int len = cm1 * dm0;
        len *= e_type_size;

        slave_acemesh_athread_put(0, psrc, pdest, len, reply, 0, 0);
    }

    int counter_val = *counter;
    *counter = ++counter_val;
}

/*from the 3d c array(t3,t2,t1) to the  3d c array(d3,d2,d1) */
/* the corresponding fortran array is (t1,t2,t3) and (d1,d2,d3) respectively */
/* in fact, expand data */
// stride_no starts from 0, it must be >= 1 && <= dim_num - 1
// so,in this case, stride_no is 1 or 2
//
void slave_acemesh_copyin3d(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                            int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                            int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                            int c3_lb, int c3_ub,
#ifdef COPY_OLD
                            int e_type_size, int *reply, int *counter)
#else
                            int e_type_size, int *reply, int *counter, int *dma_bytes)
#endif
{
    c1_lb = (c1_lb < d1_lb) ? d1_lb : c1_lb;
    c1_ub = (c1_ub > d1_ub) ? d1_ub : c1_ub;

    c2_lb = (c2_lb < d2_lb) ? d2_lb : c2_lb;
    c2_ub = (c2_ub > d2_ub) ? d2_ub : c2_ub;

    c3_lb = (c3_lb < d3_lb) ? d3_lb : c3_lb;
    c3_ub = (c3_ub > d3_ub) ? d3_ub : c3_ub;

    int dm0 = d1_ub - d1_lb + 1;
    int dm1 = d2_ub - d2_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int cm2 = c3_ub - c3_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;
    int tm2 = t3_ub - t3_lb + 1;

#ifdef ACEMESH_SCHEDULER_PROFILING
#ifndef COPY_OLD
    *dma_bytes += tm0 * tm1 * tm2 * e_type_size;
#endif
#endif

    int i;
    int stride_flag = 0;
    int stride_no = 2;
    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    } else if (dm1 != cm1) {
        stride_flag = 1;
        stride_no = 1;
    }

    char *psrc = (char *)src;
    int nSrcOff = (c3_lb - d3_lb) * dm1 * dm0 + (c2_lb - d2_lb) * dm0 + (c1_lb - d1_lb);
    nSrcOff *= e_type_size;
    psrc += nSrcOff;

    char *pdest = (char *)dest;
    if (stride_no == 0) {
        int len = cm1 * cm0;
        len *= e_type_size;

        int stride = dm0 - cm0;
        stride *= e_type_size;

        int bsize = cm0;
        bsize *= e_type_size;

        int nSrcOff_i = dm1 * dm0;
        nSrcOff_i *= e_type_size;

        int nDestOff_i = tm1 * tm0;
        nDestOff_i *= e_type_size;

        for (i = c3_lb; i <= c3_ub; i++) {
            slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);

            psrc += nSrcOff_i;
            pdest += nDestOff_i;
        }
        int counter_val = *counter;
        counter_val += cm2;
        *counter = counter_val;

    } else if (stride_no == 1) {
        int len = cm2 * cm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm1 - cm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm1;
        bsize *= dm0;
        bsize *= e_type_size;

        slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);

        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;

    } else {
        int len = cm2 * dm1 * dm0;
        len *= e_type_size;

        slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, 0, 0);
        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;
    }
}
/*from the 3d c array(d3,d2,d1) to the  3d c array(t3,t3,t1) */
/* the corresponding fortran array is (t1,t2,t3) and (d1,d2,d3) respectively */
/* in fact, compress data first before output from ldm to mm */
void slave_acemesh_copyout3d(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                             int c3_lb, int c3_ub,
#ifdef COPY_OLD
                             int e_type_size, int *reply, int *counter)
#else
                             int e_type_size, int *reply, int *counter, int *dma_bytes)
#endif
{
    c1_lb = (c1_lb < d1_lb) ? d1_lb : c1_lb;
    c1_ub = (c1_ub > d1_ub) ? d1_ub : c1_ub;

    c2_lb = (c2_lb < d2_lb) ? d2_lb : c2_lb;
    c2_ub = (c2_ub > d2_ub) ? d2_ub : c2_ub;

    c3_lb = (c3_lb < d3_lb) ? d3_lb : c3_lb;
    c3_ub = (c3_ub > d3_ub) ? d3_ub : c3_ub;

    int dm0 = d1_ub - d1_lb + 1;
    int dm1 = d2_ub - d2_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int cm2 = c3_ub - c3_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;
    int tm2 = t3_ub - t3_lb + 1;
#ifdef ACEMESH_SCHEDULER_PROFILING
#ifndef COPY_OLD
    *dma_bytes += tm0 * tm1 * tm2 * e_type_size;
#endif
#endif
    int i;
    int stride_flag = 0;
    int stride_no = 2;
    int reshape_flag = 0;

    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    } else if (dm1 != cm1) {
        stride_flag = 1;
        stride_no = 1;
    }

    if (tm0 != cm0) {
        reshape_flag = 1;
    } else if (tm1 != cm1) {
        reshape_flag = 1;
    }

    if (reshape_flag == 1) {
        if (stride_no == 2) {
            stride_no = 1;
        }
    }

    char *psrc = (char *)src;

    char *pdest = (char *)dest;
    int nDestOff = (c3_lb - d3_lb) * dm1 * dm0 + (c2_lb - d2_lb) * dm0 + (c1_lb - d1_lb);
    nDestOff *= e_type_size;
    pdest += nDestOff;

    if (stride_no == 0) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout3d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, e_type_size, 1);
        }
        int len = cm1 * cm0;
        len *= e_type_size;

        int stride = dm0 - cm0;
        stride *= e_type_size;

        int bsize = cm0;
        bsize *= e_type_size;

        int nSrcOff_i = tm1 * tm0;
        nSrcOff_i *= e_type_size;

        int nDestOff_i = dm1 * dm0;
        nDestOff_i *= e_type_size;

        for (i = c3_lb; i <= c3_ub; i++) {
            slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);

            psrc += nSrcOff_i;
            pdest += nDestOff_i;
        }
        int counter_val = *counter;
        counter_val += cm2;
        *counter = counter_val;

    } else if (stride_no == 1) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout3d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, e_type_size, 2);
        }

        int len = cm2 * cm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm1 - cm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm1;
        bsize *= dm0;
        bsize *= e_type_size;

        slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);

        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;
    } else {
        int len = cm2 * dm1 * dm0;
        len *= e_type_size;

        slave_acemesh_athread_put(0, psrc, pdest, len, reply, 0, 0);
        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;
    }
}
void slave_acemesh_copyin4d(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                            int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                            int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                            int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                            int c4_lb, int c4_ub,
#ifdef COPY_OLD
                            int e_type_size, int *reply, int *counter)
#else
                            int e_type_size, int *reply, int *counter, int *dma_bytes)
#endif
{
    c1_lb = (c1_lb < d1_lb) ? d1_lb : c1_lb;
    c1_ub = (c1_ub > d1_ub) ? d1_ub : c1_ub;

    c2_lb = (c2_lb < d2_lb) ? d2_lb : c2_lb;
    c2_ub = (c2_ub > d2_ub) ? d2_ub : c2_ub;

    c3_lb = (c3_lb < d3_lb) ? d3_lb : c3_lb;
    c3_ub = (c3_ub > d3_ub) ? d3_ub : c3_ub;

    c4_lb = (c4_lb < d4_lb) ? d4_lb : c4_lb;
    c4_ub = (c4_ub > d4_ub) ? d4_ub : c4_ub;

    int dm0 = d1_ub - d1_lb + 1;
    int dm1 = d2_ub - d2_lb + 1;
    int dm2 = d3_ub - d3_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int cm2 = c3_ub - c3_lb + 1;
    int cm3 = c4_ub - c4_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;
    int tm2 = t3_ub - t3_lb + 1;
    int tm3 = t4_ub - t4_lb + 1;

#ifdef ACEMESH_SCHEDULER_PROFILING
#ifndef COPY_OLD
    *dma_bytes += tm0 * tm1 * tm2 * tm3 * e_type_size;
#endif
#endif
    int i, j;
    int stride_flag = 0;
    int stride_no = 3;
    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    } else if (dm1 != cm1) {
        stride_flag = 1;
        stride_no = 1;

    } else if (dm2 != cm2) {
        stride_flag = 1;
        stride_no = 2;
    }

    char *psrc = (char *)src;
    int nSrcOff = (c4_lb - d4_lb) * dm2 * dm1 * dm0 + (c3_lb - d3_lb) * dm1 * dm0 +
                  (c2_lb - d2_lb) * dm0 + (c1_lb - d1_lb);
    nSrcOff *= e_type_size;
    psrc += nSrcOff;

    char *pdest = (char *)dest;
    if (stride_no == 0) {
        int len = cm1 * cm0;
        len *= e_type_size;

        int stride = dm0 - cm0;
        stride *= e_type_size;

        int bsize = cm0;
        bsize *= e_type_size;

        int nSrcOff_i = dm1 * dm0;
        nSrcOff_i *= e_type_size;

        int nDestOff_i = tm1 * tm0;
        nDestOff_i *= e_type_size;

        int nSrcOff_j = dm2 * dm1 * dm0;
        nSrcOff_j *= e_type_size;

        int nDestOff_j = tm2 * tm1 * tm0;
        nDestOff_j *= e_type_size;

        char *psrc_j = psrc;
        char *pdest_j = pdest;
        for (j = c4_lb; j <= c4_ub; j++) {
            psrc = psrc_j;
            pdest = pdest_j;
            for (i = c3_lb; i <= c3_ub; i++) {
                slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);

                psrc += nSrcOff_i;
                pdest += nDestOff_i;
            }
            psrc_j += nSrcOff_j;
            pdest_j += nDestOff_j;
        }
        int counter_val = *counter;
        counter_val += (cm3 * cm2);
        *counter = counter_val;

    } else if (stride_no == 1) {
        int len = cm2 * cm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm1 - cm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm1;
        bsize *= dm0;
        bsize *= e_type_size;

        int nSrcOff_j = dm2 * dm1 * dm0;
        nSrcOff_j *= e_type_size;

        int nDestOff_j = tm2 * tm1 * tm0;
        nDestOff_j *= e_type_size;

        for (j = c4_lb; j <= c4_ub; j++) {
            slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);

            psrc += nSrcOff_j;
            pdest += nDestOff_j;
        }
        int counter_val = *counter;
        counter_val += cm3;
        *counter = counter_val;
    } else if (stride_no == 2) {
        int len = cm3 * cm2;
        len *= dm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm2 - cm2;
        stride *= dm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm2;
        bsize *= dm1;
        bsize *= dm0;
        bsize *= e_type_size;

        slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);

        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;

    } else {
        int len = cm3 * dm2 * dm1 * dm0;
        len *= e_type_size;

        slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, 0, 0);
        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;
    }
}
void slave_acemesh_copyout4d(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                             int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                             int c4_lb, int c4_ub,
#ifdef COPY_OLD
                             int e_type_size, int *reply, int *counter)
#else
                             int e_type_size, int *reply, int *counter, int *dma_bytes)
#endif
{
    c1_lb = (c1_lb < d1_lb) ? d1_lb : c1_lb;
    c1_ub = (c1_ub > d1_ub) ? d1_ub : c1_ub;

    c2_lb = (c2_lb < d2_lb) ? d2_lb : c2_lb;
    c2_ub = (c2_ub > d2_ub) ? d2_ub : c2_ub;

    c3_lb = (c3_lb < d3_lb) ? d3_lb : c3_lb;
    c3_ub = (c3_ub > d3_ub) ? d3_ub : c3_ub;

    c4_lb = (c4_lb < d4_lb) ? d4_lb : c4_lb;
    c4_ub = (c4_ub > d4_ub) ? d4_ub : c4_ub;

    int dm0 = d1_ub - d1_lb + 1;
    int dm1 = d2_ub - d2_lb + 1;
    int dm2 = d3_ub - d3_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int cm2 = c3_ub - c3_lb + 1;
    int cm3 = c4_ub - c4_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;
    int tm2 = t3_ub - t3_lb + 1;
    int tm3 = t4_ub - t4_lb + 1;

#ifdef ACEMESH_SCHEDULER_PROFILING
#ifndef COPY_OLD
    *dma_bytes += tm0 * tm1 * tm2 * tm3 * e_type_size;
#endif
#endif
    int i, j;
    int stride_flag = 0;
    int stride_no = 3;
    int reshape_flag = 0;
    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    } else if (dm1 != cm1) {
        stride_flag = 1;
        stride_no = 1;
    } else if (dm2 != cm2) {
        stride_flag = 1;
        stride_no = 2;
    }

    if (tm0 != cm0) {
        reshape_flag = 1;
    } else if (tm1 != cm1) {
        reshape_flag = 1;
    } else if (tm2 != cm2) {
        reshape_flag = 1;
    }

    if (reshape_flag == 1) {
        if (stride_no == 3) {
            stride_no = 2;
        }
    }

    char *psrc = (char *)src;

    char *pdest = (char *)dest;
    int nDestOff = (c4_lb - d4_lb) * dm2 * dm1 * dm0 + (c3_lb - d3_lb) * dm1 * dm0 +
                   (c2_lb - d2_lb) * dm0 + (c1_lb - d1_lb);
    nDestOff *= e_type_size;
    pdest += nDestOff;

    if (stride_no == 0) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout4d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3,
                                            e_type_size, 1);
        }

        int len = cm1 * cm0;
        len *= e_type_size;

        int stride = dm0 - cm0;
        stride *= e_type_size;

        int bsize = cm0;
        bsize *= e_type_size;

        int nSrcOff_j = tm2 * tm1 * tm0;
        nSrcOff_j *= e_type_size;

        int nDestOff_j = dm2 * dm1 * dm0;
        nDestOff_j *= e_type_size;

        int nSrcOff_i = tm1 * tm0;
        nSrcOff_i *= e_type_size;

        int nDestOff_i = dm1 * dm0;
        nDestOff_i *= e_type_size;
        char *psrc_j = psrc;
        char *pdest_j = pdest;
        for (j = c4_lb; j <= c4_ub; j++) {
            psrc = psrc_j;
            pdest = pdest_j;
            for (i = c3_lb; i <= c3_ub; i++) {
                slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);

                psrc += nSrcOff_i;
                pdest += nDestOff_i;
            }
            psrc_j += nSrcOff_j;
            pdest_j += nDestOff_j;
        }
        int counter_val = *counter;
        counter_val += (cm3 * cm2);
        *counter = counter_val;
    } else if (stride_no == 1) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout4d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3,
                                            e_type_size, 2);
        }

        int len = cm2 * cm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm1 - cm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm1;
        bsize *= dm0;
        bsize *= e_type_size;

        int nSrcOff_j = tm2 * tm1 * tm0;
        nSrcOff_j *= e_type_size;

        int nDestOff_j = dm2 * dm1 * dm0;
        nDestOff_j *= e_type_size;

        for (j = c4_lb; j <= c4_ub; j++) {
            slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);

            psrc += nSrcOff_j;
            pdest += nDestOff_j;
        }
        int counter_val = *counter;
        counter_val += cm3;
        *counter = counter_val;
    } else if (stride_no == 2) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout4d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3,
                                            e_type_size, 3);
        }
        int len = cm3 * cm2;
        len *= dm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm2 - cm2;
        stride *= dm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm2;
        bsize *= dm1;
        bsize *= dm0;
        bsize *= e_type_size;

        slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);

        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;

    } else {
        int len = cm3 * dm2 * dm1 * dm0;
        len *= e_type_size;

        slave_acemesh_athread_put(0, psrc, pdest, len, reply, 0, 0);
        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;
    }
}
void slave_acemesh_copyin5d(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                            int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                            int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                            int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                            int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                            int c5_lb, int c5_ub,
#ifdef COPY_OLD
                            int e_type_size, int *reply, int *counter)
#else
                            int e_type_size, int *reply, int *counter, int *dma_bytes)
#endif
{
    c1_lb = (c1_lb < d1_lb) ? d1_lb : c1_lb;
    c1_ub = (c1_ub > d1_ub) ? d1_ub : c1_ub;

    c2_lb = (c2_lb < d2_lb) ? d2_lb : c2_lb;
    c2_ub = (c2_ub > d2_ub) ? d2_ub : c2_ub;

    c3_lb = (c3_lb < d3_lb) ? d3_lb : c3_lb;
    c3_ub = (c3_ub > d3_ub) ? d3_ub : c3_ub;

    c4_lb = (c4_lb < d4_lb) ? d4_lb : c4_lb;
    c4_ub = (c4_ub > d4_ub) ? d4_ub : c4_ub;

    c5_lb = (c5_lb < d5_lb) ? d5_lb : c5_lb;
    c5_ub = (c5_ub > d5_ub) ? d5_ub : c5_ub;

    int dm0 = d1_ub - d1_lb + 1;
    int dm1 = d2_ub - d2_lb + 1;
    int dm2 = d3_ub - d3_lb + 1;
    int dm3 = d4_ub - d4_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int cm2 = c3_ub - c3_lb + 1;
    int cm3 = c4_ub - c4_lb + 1;
    int cm4 = c5_ub - c5_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;
    int tm2 = t3_ub - t3_lb + 1;
    int tm3 = t4_ub - t4_lb + 1;
    int tm4 = t5_ub - t5_lb + 1;

#ifdef ACEMESH_SCHEDULER_PROFILING
#ifndef COPY_OLD
    *dma_bytes += tm0 * tm1 * tm2 * tm3 * tm4 * e_type_size;
#endif
#endif
    int i, j, k;
    int stride_flag = 0;
    int stride_no = 4;
    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    } else if (dm1 != cm1) {
        stride_flag = 1;
        stride_no = 1;
    } else if (dm2 != cm2) {
        stride_flag = 1;
        stride_no = 2;
    } else if (dm3 != cm3) {
        stride_flag = 1;
        stride_no = 3;
    }

    char *psrc = (char *)src;
    int nSrcOff = (c5_lb - d5_lb) * dm3 * dm2 * dm1 * dm0 + (c4_lb - d4_lb) * dm2 * dm1 * dm0 +
                  (c3_lb - d3_lb) * dm1 * dm0 + (c2_lb - d2_lb) * dm0 + (c1_lb - d1_lb);
    nSrcOff *= e_type_size;
    psrc += nSrcOff;

    char *pdest = (char *)dest;
    if (stride_no == 0) {
        int len = cm1 * cm0;
        len *= e_type_size;

        int stride = dm0 - cm0;
        stride *= e_type_size;

        int bsize = cm0;
        bsize *= e_type_size;

        int nSrcOff_k = dm3 * dm2 * dm1 * dm0;
        nSrcOff_k *= e_type_size;

        int nDestOff_k = tm3 * tm2 * tm1 * tm0;
        nDestOff_k *= e_type_size;

        int nSrcOff_j = dm2 * dm1 * dm0;
        nSrcOff_j *= e_type_size;

        int nDestOff_j = tm2 * tm1 * tm0;
        nDestOff_j *= e_type_size;

        int nSrcOff_i = dm1 * dm0;
        nSrcOff_i *= e_type_size;

        int nDestOff_i = tm1 * tm0;
        nDestOff_i *= e_type_size;

        char *psrc_j = psrc;
        char *pdest_j = pdest;

        char *psrc_k = psrc;
        char *pdest_k = pdest;
        for (k = c5_lb; k <= c5_ub; k++) {
            psrc_j = psrc_k;
            pdest_j = pdest_k;
            for (j = c4_lb; j <= c4_ub; j++) {
                psrc = psrc_j;
                pdest = pdest_j;
                for (i = c3_lb; i <= c3_ub; i++) {
                    slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);
                    psrc += nSrcOff_i;
                    pdest += nDestOff_i;
                }
                psrc_j += nSrcOff_j;
                pdest_j += nDestOff_j;
            }
            psrc_k += nSrcOff_k;
            pdest_k += nDestOff_k;
        }
        int counter_val = *counter;
        counter_val += (cm4 * cm3 * cm2);
        *counter = counter_val;
    } else if (stride_no == 1) {
        int len = cm2 * cm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm1 - cm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm1;
        bsize *= dm0;
        bsize *= e_type_size;

        int nSrcOff_k = dm3 * dm2 * dm1 * dm0;
        nSrcOff_k *= e_type_size;

        int nDestOff_k = tm3 * tm2 * tm1 * tm0;
        nDestOff_k *= e_type_size;

        int nSrcOff_j = dm2 * dm1 * dm0;
        nSrcOff_j *= e_type_size;

        int nDestOff_j = tm2 * tm1 * tm0;
        nDestOff_j *= e_type_size;

        char *psrc_k = psrc;
        char *pdest_k = pdest;
        for (k = c5_lb; k <= c5_ub; k++) {
            psrc = psrc_k;
            pdest = pdest_k;
            for (j = c4_lb; j <= c4_ub; j++) {
                slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);

                psrc += nSrcOff_j;
                pdest += nDestOff_j;
            }
            psrc_k += nSrcOff_k;
            pdest_k += nDestOff_k;
        }
        int counter_val = *counter;
        counter_val += (cm4 * cm3);
        *counter = counter_val;
    } else if (stride_no == 2) {
        int len = cm3 * cm2;
        len *= dm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm2 - cm2;
        stride *= dm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm2;
        bsize *= dm1;
        bsize *= dm0;
        bsize *= e_type_size;

        int nSrcOff_k = dm3 * dm2 * dm1 * dm0;
        nSrcOff_k *= e_type_size;

        int nDestOff_k = tm3 * tm2 * tm1 * tm0;
        nDestOff_k *= e_type_size;
        for (k = c5_lb; k <= c5_ub; k++) {
            slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);

            psrc += nSrcOff_k;
            pdest += nDestOff_k;
        }
        int counter_val = *counter;
        counter_val += cm4;
        *counter = counter_val;

    } else if (stride_no == 3) {
        int len = cm4 * cm3;
        len *= dm2;
        len *= dm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm3 - cm3;
        stride *= dm2;
        stride *= dm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm3;
        bsize *= dm2;
        bsize *= dm1;
        bsize *= dm0;
        bsize *= e_type_size;
        slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);

        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;
    } else {
        int len = cm4 * dm3 * dm2 * dm1 * dm0;
        len *= e_type_size;

        slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, 0, 0);
        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;
    }
}
void slave_acemesh_copyout5d(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                             int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                             int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                             int c5_lb, int c5_ub,
#ifdef COPY_OLD
                             int e_type_size, int *reply, int *counter)
#else
                             int e_type_size, int *reply, int *counter, int *dma_bytes)
#endif
{
    c1_lb = (c1_lb < d1_lb) ? d1_lb : c1_lb;
    c1_ub = (c1_ub > d1_ub) ? d1_ub : c1_ub;

    c2_lb = (c2_lb < d2_lb) ? d2_lb : c2_lb;
    c2_ub = (c2_ub > d2_ub) ? d2_ub : c2_ub;

    c3_lb = (c3_lb < d3_lb) ? d3_lb : c3_lb;
    c3_ub = (c3_ub > d3_ub) ? d3_ub : c3_ub;

    c4_lb = (c4_lb < d4_lb) ? d4_lb : c4_lb;
    c4_ub = (c4_ub > d4_ub) ? d4_ub : c4_ub;

    c5_lb = (c5_lb < d5_lb) ? d5_lb : c5_lb;
    c5_ub = (c5_ub > d5_ub) ? d5_ub : c5_ub;

    int dm0 = d1_ub - d1_lb + 1;
    int dm1 = d2_ub - d2_lb + 1;
    int dm2 = d3_ub - d3_lb + 1;
    int dm3 = d4_ub - d4_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int cm2 = c3_ub - c3_lb + 1;
    int cm3 = c4_ub - c4_lb + 1;
    int cm4 = c5_ub - c5_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;
    int tm2 = t3_ub - t3_lb + 1;
    int tm3 = t4_ub - t4_lb + 1;
    int tm4 = t5_ub - t5_lb + 1;

#ifdef ACEMESH_SCHEDULER_PROFILING
#ifndef COPY_OLD
    *dma_bytes += tm0 * tm1 * tm2 * tm3 * tm4 * e_type_size;
#endif
#endif
    int i, j, k;
    int stride_flag = 0;
    int stride_no = 4;
    int reshape_flag = 0;
    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    } else if (dm1 != cm1) {
        stride_flag = 1;
        stride_no = 1;
    } else if (dm2 != cm2) {
        stride_flag = 1;
        stride_no = 2;
    } else if (dm3 != cm3) {
        stride_flag = 1;
        stride_no = 3;
    }
    if (tm0 != cm0) {
        reshape_flag = 1;
    } else if (tm1 != cm1) {
        reshape_flag = 1;
    } else if (tm2 != cm2) {
        reshape_flag = 1;
    } else if (tm3 != cm3) {
        reshape_flag = 1;
    }
    if (reshape_flag == 1) {
        if (stride_no == 4) {
            stride_no = 3;
        }
    }

    char *psrc = (char *)src;

    char *pdest = (char *)dest;
    int nDestOff = (c5_lb - d5_lb) * dm3 * dm2 * dm1 * dm0 + (c4_lb - d4_lb) * dm2 * dm1 * dm0 +
                   (c3_lb - d3_lb) * dm1 * dm0 + (c2_lb - d2_lb) * dm0 + (c1_lb - d1_lb);
    nDestOff *= e_type_size;
    pdest += nDestOff;

    if (stride_no == 0) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout5d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4,
                                            e_type_size, 1);
        }

        int len = cm1 * cm0;
        len *= e_type_size;

        int stride = dm0 - cm0;
        stride *= e_type_size;

        int bsize = cm0;
        bsize *= e_type_size;

        int nSrcOff_k = tm3 * tm2 * tm1 * tm0;
        nSrcOff_k *= e_type_size;

        int nDestOff_k = dm3 * dm2 * dm1 * dm0;
        nDestOff_k *= e_type_size;

        int nSrcOff_j = tm2 * tm1 * tm0;
        nSrcOff_j *= e_type_size;

        int nDestOff_j = dm2 * dm1 * dm0;
        nDestOff_j *= e_type_size;
        int nSrcOff_i = tm1 * tm0;
        nSrcOff_i *= e_type_size;

        int nDestOff_i = dm1 * dm0;
        nDestOff_i *= e_type_size;

        char *psrc_j = psrc;
        char *pdest_j = pdest;

        char *psrc_k = psrc;
        char *pdest_k = pdest;
        for (k = c5_lb; k <= c5_ub; k++) {
            psrc_j = psrc_k;
            pdest_j = pdest_k;
            for (j = c4_lb; j <= c4_ub; j++) {
                psrc = psrc_j;
                pdest = pdest_j;
                for (i = c3_lb; i <= c3_ub; i++) {
                    slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);
                    psrc += nSrcOff_i;
                    pdest += nDestOff_i;
                }
                psrc_j += nSrcOff_j;
                pdest_j += nDestOff_j;
            }
            psrc_k += nSrcOff_k;
            pdest_k += nDestOff_k;
        }
        int counter_val = *counter;
        counter_val += (cm4 * cm3 * cm2);
        *counter = counter_val;
    } else if (stride_no == 1) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout5d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4,
                                            e_type_size, 2);
        }
        int len = cm2 * cm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm1 - cm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm1;
        bsize *= dm0;
        bsize *= e_type_size;

        int nSrcOff_k = tm3 * tm2 * tm1 * tm0;
        nSrcOff_k *= e_type_size;

        int nDestOff_k = dm3 * dm2 * dm1 * dm0;
        nDestOff_k *= e_type_size;

        int nSrcOff_j = tm2 * tm1 * tm0;
        nSrcOff_j *= e_type_size;

        int nDestOff_j = dm2 * dm1 * dm0;
        nDestOff_j *= e_type_size;

        char *psrc_k = psrc;
        char *pdest_k = pdest;

        for (k = c5_lb; k <= c5_ub; k++) {
            psrc = psrc_k;
            pdest = pdest_k;
            for (j = c4_lb; j <= c4_ub; j++) {
                slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);

                psrc += nSrcOff_j;
                pdest += nDestOff_j;
            }
            psrc_k += nSrcOff_k;
            pdest_k += nDestOff_k;
        }
        int counter_val = *counter;
        counter_val += (cm4 * cm3);
        *counter = counter_val;
    } else if (stride_no == 2) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout5d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4,
                                            e_type_size, 3);
        }
        int len = cm3 * cm2;
        len *= dm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm2 - cm2;
        stride *= dm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm2;
        bsize *= dm1;
        bsize *= dm0;
        bsize *= e_type_size;

        int nSrcOff_k = tm3 * tm2 * tm1 * tm0;
        nSrcOff_k *= e_type_size;

        int nDestOff_k = dm3 * dm2 * dm1 * dm0;
        nDestOff_k *= e_type_size;
        for (k = c5_lb; k <= c5_ub; k++) {
            slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);

            psrc += nSrcOff_k;
            pdest += nDestOff_k;
        }
        int counter_val = *counter;
        counter_val += cm4;
        *counter = counter_val;

    } else if (stride_no == 3) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout5d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4,
                                            e_type_size, 4);
        }
        int len = cm4 * cm3;
        len *= dm2;
        len *= dm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm3 - cm3;
        stride *= dm2;
        stride *= dm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm3;
        bsize *= dm2;
        bsize *= dm1;
        bsize *= dm0;
        bsize *= e_type_size;

        slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);

        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;
    } else {
        int len = cm3 * dm2 * dm1 * dm0;
        len *= e_type_size;

        slave_acemesh_athread_put(0, psrc, pdest, len, reply, 0, 0);
        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;
    }
}
void slave_acemesh_copyin6d(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                            int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                            int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                            int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                            int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                            int c5_lb, int c5_ub, int d6_lb, int d6_ub, int t6_lb, int t6_ub,
                            int c6_lb, int c6_ub,
#ifdef COPY_OLD
                            int e_type_size, int *reply, int *counter)
#else
                            int e_type_size, int *reply, int *counter, int *dma_bytes)
#endif
{
    c1_lb = (c1_lb < d1_lb) ? d1_lb : c1_lb;
    c1_ub = (c1_ub > d1_ub) ? d1_ub : c1_ub;

    c2_lb = (c2_lb < d2_lb) ? d2_lb : c2_lb;
    c2_ub = (c2_ub > d2_ub) ? d2_ub : c2_ub;

    c3_lb = (c3_lb < d3_lb) ? d3_lb : c3_lb;
    c3_ub = (c3_ub > d3_ub) ? d3_ub : c3_ub;

    c4_lb = (c4_lb < d4_lb) ? d4_lb : c4_lb;
    c4_ub = (c4_ub > d4_ub) ? d4_ub : c4_ub;

    c5_lb = (c5_lb < d5_lb) ? d5_lb : c5_lb;
    c5_ub = (c5_ub > d5_ub) ? d5_ub : c5_ub;

    c6_lb = (c6_lb < d6_lb) ? d6_lb : c6_lb;
    c6_ub = (c6_ub > d6_ub) ? d6_ub : c6_ub;

    int dm0 = d1_ub - d1_lb + 1;
    int dm1 = d2_ub - d2_lb + 1;
    int dm2 = d3_ub - d3_lb + 1;
    int dm3 = d4_ub - d4_lb + 1;
    int dm4 = d5_ub - d5_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int cm2 = c3_ub - c3_lb + 1;
    int cm3 = c4_ub - c4_lb + 1;
    int cm4 = c5_ub - c5_lb + 1;
    int cm5 = c6_ub - c6_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;
    int tm2 = t3_ub - t3_lb + 1;
    int tm3 = t4_ub - t4_lb + 1;
    int tm4 = t5_ub - t5_lb + 1;
    int tm5 = t6_ub - t6_lb + 1;

#ifdef ACEMESH_SCHEDULER_PROFILING
#ifndef COPY_OLD
    *dma_bytes += tm0 * tm1 * tm2 * tm3 * tm4 * tm5 * e_type_size;
#endif
#endif
    int i, j, k, m;
    int stride_flag = 0;
    int stride_no = 5;
    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    } else if (dm1 != cm1) {
        stride_flag = 1;
        stride_no = 1;
    } else if (dm2 != cm2) {
        stride_flag = 1;
        stride_no = 2;
    } else if (dm3 != cm3) {
        stride_flag = 1;
        stride_no = 3;
    } else if (dm4 != cm4) {
        stride_flag = 1;
        stride_no = 4;
    }
    char *psrc = (char *)src;
    int nSrcOff = (c6_lb - d6_lb) * dm4 * dm3 * dm2 * dm1 * dm0 +
                  (c5_lb - d5_lb) * dm3 * dm2 * dm1 * dm0 + (c4_lb - d4_lb) * dm2 * dm1 * dm0 +
                  (c3_lb - d3_lb) * dm1 * dm0 + (c2_lb - d2_lb) * dm0 + (c1_lb - d1_lb);
    nSrcOff *= e_type_size;
    psrc += nSrcOff;

    char *pdest = (char *)dest;
    if (stride_no == 0) {
        int len = cm1 * cm0;
        len *= e_type_size;

        int stride = dm0 - cm0;
        stride *= e_type_size;

        int bsize = cm0;
        bsize *= e_type_size;

        int nSrcOff_m = dm4 * dm3 * dm2 * dm1 * dm0;
        nSrcOff_m *= e_type_size;

        int nDestOff_m = tm4 * tm3 * tm2 * tm1 * tm0;
        nDestOff_m *= e_type_size;

        int nSrcOff_k = dm3 * dm2 * dm1 * dm0;
        nSrcOff_k *= e_type_size;

        int nDestOff_k = tm3 * tm2 * tm1 * tm0;
        nDestOff_k *= e_type_size;

        int nSrcOff_j = dm2 * dm1 * dm0;
        nSrcOff_j *= e_type_size;

        int nDestOff_j = tm2 * tm1 * tm0;
        nDestOff_j *= e_type_size;

        int nSrcOff_i = dm1 * dm0;
        nSrcOff_i *= e_type_size;

        int nDestOff_i = tm1 * tm0;
        nDestOff_i *= e_type_size;

        char *psrc_j = psrc;
        char *pdest_j = pdest;

        char *psrc_k = psrc;
        char *pdest_k = pdest;

        char *psrc_m = psrc;
        char *pdest_m = pdest;
        for (m = c6_lb; m <= c6_ub; m++) {
            psrc_k = psrc_m;
            pdest_k = pdest_m;
            for (k = c5_lb; k <= c5_ub; k++) {
                psrc_j = psrc_k;
                pdest_j = pdest_k;
                for (j = c4_lb; j <= c4_ub; j++) {
                    psrc = psrc_j;
                    pdest = pdest_j;
                    for (i = c3_lb; i <= c3_ub; i++) {
                        slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);

                        psrc += nSrcOff_i;

                        pdest += nDestOff_i;
                    }
                    psrc_j += nSrcOff_j;
                    pdest_j += nDestOff_j;
                }
                psrc_k += nSrcOff_k;
                pdest_k += nDestOff_k;
            }
            psrc_m += nSrcOff_m;
            pdest_m += nDestOff_m;
        }
        int counter_val = *counter;
        counter_val += (cm5 * cm4 * cm3 * cm2);
        *counter = counter_val;
    } else if (stride_no == 1) {
        int len = cm2 * cm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm1 - cm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm1;
        bsize *= dm0;
        bsize *= e_type_size;

        int nSrcOff_m = dm4 * dm3 * dm2 * dm1 * dm0;
        nSrcOff_m *= e_type_size;

        int nDestOff_m = tm4 * tm3 * tm2 * tm1 * tm0;
        nDestOff_m *= e_type_size;

        int nSrcOff_k = dm3 * dm2 * dm1 * dm0;
        nSrcOff_k *= e_type_size;

        int nDestOff_k = tm3 * tm2 * tm1 * tm0;
        nDestOff_k *= e_type_size;

        int nSrcOff_j = dm2 * dm1 * dm0;
        nSrcOff_j *= e_type_size;

        int nDestOff_j = tm2 * tm1 * tm0;
        nDestOff_j *= e_type_size;

        char *psrc_m = psrc;
        char *pdest_m = pdest;

        char *psrc_k = psrc;
        char *pdest_k = pdest;

        for (m = c6_lb; m <= c6_ub; m++) {
            psrc_k = psrc_m;
            pdest_k = pdest_m;
            for (k = c5_lb; k <= c5_ub; k++) {
                psrc = psrc_k;
                pdest = pdest_k;
                for (j = c4_lb; j <= c4_ub; j++) {
                    slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);
                    psrc += nSrcOff_j;
                    pdest += nDestOff_j;
                }
                psrc_k += nSrcOff_k;
                pdest_k += nDestOff_k;
            }
            psrc_m += nSrcOff_m;
            pdest_m += nDestOff_m;
        }
        int counter_val = *counter;
        counter_val += (cm5 * cm4 * cm3);
        *counter = counter_val;
    } else if (stride_no == 2) {
        int len = cm3 * cm2;
        len *= dm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm2 - cm2;
        stride *= dm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm2;
        bsize *= dm1;
        bsize *= dm0;
        bsize *= e_type_size;

        int nSrcOff_m = dm4 * dm3 * dm2 * dm1 * dm0;
        nSrcOff_m *= e_type_size;

        int nDestOff_m = tm4 * tm3 * tm2 * tm1 * tm0;
        nDestOff_m *= e_type_size;

        int nSrcOff_k = dm3 * dm2 * dm1 * dm0;
        nSrcOff_k *= e_type_size;

        int nDestOff_k = tm3 * tm2 * tm1 * tm0;
        nDestOff_k *= e_type_size;

        char *psrc_m = psrc;
        char *pdest_m = pdest;

        for (m = c6_lb; m <= c6_ub; m++) {
            psrc = psrc_m;
            pdest = pdest_m;
            for (k = c5_lb; k <= c5_ub; k++) {
                slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);

                psrc += nSrcOff_k;
                pdest += nDestOff_k;
            }
            psrc_m += nSrcOff_m;
            pdest_m += nDestOff_m;
        }
        int counter_val = *counter;
        counter_val += (cm5 * cm4);
        *counter = counter_val;
    } else if (stride_no == 3) {
        int len = cm4 * cm3;
        len *= dm2;
        len *= dm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm3 - cm3;
        stride *= dm2;
        stride *= dm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm3;
        bsize *= dm2;
        bsize *= dm1;
        bsize *= dm0;
        bsize *= e_type_size;

        int nSrcOff_m = dm4 * dm3 * dm2 * dm1 * dm0;
        nSrcOff_m *= e_type_size;

        int nDestOff_m = tm4 * tm3 * tm2 * tm1 * tm0;
        nDestOff_m *= e_type_size;
        for (m = c6_lb; m <= c6_ub; m++) {
            slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);

            psrc += nSrcOff_m;
            pdest += nDestOff_m;
        }
        int counter_val = *counter;
        counter_val += cm5;
        *counter = counter_val;
    } else if (stride_no == 4) {
        int len = cm5 * cm4;
        len *= dm3;
        len *= dm2;
        len *= dm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm4 - cm4;
        stride *= dm3;
        stride *= dm2;
        stride *= dm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm4;
        bsize *= dm3;
        bsize *= dm2;
        bsize *= dm1;
        bsize *= dm0;
        bsize *= e_type_size;

        slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, stride, bsize);

        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;
    } else {
        int len = cm5 * dm4 * dm3 * dm2 * dm1 * dm0;
        len *= e_type_size;

        slave_acemesh_athread_get(0, psrc, pdest, len, reply, 0, 0, 0);
        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;
    }
}
void slave_acemesh_copyout6d(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                             int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                             int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                             int c5_lb, int c5_ub, int d6_lb, int d6_ub, int t6_lb, int t6_ub,
                             int c6_lb, int c6_ub,
#ifdef COPY_OLD
                             int e_type_size, int *reply, int *counter)
#else
                             int e_type_size, int *reply, int *counter, int *dma_bytes)
#endif
{
    c1_lb = (c1_lb < d1_lb) ? d1_lb : c1_lb;
    c1_ub = (c1_ub > d1_ub) ? d1_ub : c1_ub;

    c2_lb = (c2_lb < d2_lb) ? d2_lb : c2_lb;
    c2_ub = (c2_ub > d2_ub) ? d2_ub : c2_ub;

    c3_lb = (c3_lb < d3_lb) ? d3_lb : c3_lb;
    c3_ub = (c3_ub > d3_ub) ? d3_ub : c3_ub;

    c4_lb = (c4_lb < d4_lb) ? d4_lb : c4_lb;
    c4_ub = (c4_ub > d4_ub) ? d4_ub : c4_ub;

    c5_lb = (c5_lb < d5_lb) ? d5_lb : c5_lb;
    c5_ub = (c5_ub > d5_ub) ? d5_ub : c5_ub;

    c6_lb = (c6_lb < d6_lb) ? d6_lb : c6_lb;
    c6_ub = (c6_ub > d6_ub) ? d6_ub : c6_ub;

    int dm0 = d1_ub - d1_lb + 1;
    int dm1 = d2_ub - d2_lb + 1;
    int dm2 = d3_ub - d3_lb + 1;
    int dm3 = d4_ub - d4_lb + 1;
    int dm4 = d5_ub - d5_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int cm2 = c3_ub - c3_lb + 1;
    int cm3 = c4_ub - c4_lb + 1;
    int cm4 = c5_ub - c5_lb + 1;
    int cm5 = c6_ub - c6_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;
    int tm2 = t3_ub - t3_lb + 1;
    int tm3 = t4_ub - t4_lb + 1;
    int tm4 = t5_ub - t5_lb + 1;
    int tm5 = t6_ub - t6_lb + 1;
#ifdef ACEMESH_SCHEDULER_PROFILING
#ifndef COPY_OLD
    *dma_bytes += tm0 * tm1 * tm2 * tm3 * tm4 * tm5 * e_type_size;
#endif
#endif
    int i, j, k, m;
    int stride_flag = 0;
    int stride_no = 5;
    int reshape_flag = 0;

    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    } else if (dm1 != cm1) {
        stride_flag = 1;
        stride_no = 1;
    } else if (dm2 != cm2) {
        stride_flag = 1;
        stride_no = 2;
    } else if (dm3 != cm3) {
        stride_flag = 1;
        stride_no = 3;
    } else if (dm4 != cm4) {
        stride_flag = 1;
        stride_no = 4;
    }

    if (tm0 != cm0) {
        reshape_flag = 1;
    } else if (tm1 != cm1) {
        reshape_flag = 1;
    } else if (tm2 != cm2) {
        reshape_flag = 1;
    } else if (tm3 != cm3) {
        reshape_flag = 1;
    } else if (tm4 != cm4) {
        reshape_flag = 1;
    }

    if (reshape_flag == 1) {
        if (stride_no == 5) {
            stride_no = 4;
        }
    }

    char *psrc = (char *)src;

    char *pdest = (char *)dest;
    int nDestOff = (c6_lb - d6_lb) * dm4 * dm3 * dm2 * dm1 * dm0 +
                   (c5_lb - d5_lb) * dm3 * dm2 * dm1 * dm0 + (c4_lb - d4_lb) * dm2 * dm1 * dm0 +
                   (c3_lb - d3_lb) * dm1 * dm0 + (c2_lb - d2_lb) * dm0 + (c1_lb - d1_lb);
    nDestOff *= e_type_size;
    pdest += nDestOff;
    if (stride_no == 0) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout6d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4,
                                            tm5, cm5, e_type_size, 1);
        }
        int len = cm1 * cm0;
        len *= e_type_size;

        int stride = dm0 - cm0;
        stride *= e_type_size;

        int bsize = cm0;
        bsize *= e_type_size;

        int nSrcOff_m = tm4 * tm3 * tm2 * tm1 * tm0;
        nSrcOff_m *= e_type_size;

        int nDestOff_m = dm4 * dm3 * dm2 * dm1 * dm0;
        nDestOff_m *= e_type_size;

        int nSrcOff_k = tm3 * tm2 * tm1 * tm0;
        nSrcOff_k *= e_type_size;

        int nDestOff_k = dm3 * dm2 * dm1 * dm0;
        nDestOff_k *= e_type_size;

        int nSrcOff_j = tm2 * tm1 * tm0;
        nSrcOff_j *= e_type_size;

        int nDestOff_j = dm2 * dm1 * dm0;
        nDestOff_j *= e_type_size;
        int nSrcOff_i = tm1 * tm0;
        nSrcOff_i *= e_type_size;

        int nDestOff_i = dm1 * dm0;
        nDestOff_i *= e_type_size;

        char *psrc_j = psrc;
        char *pdest_j = pdest;

        char *psrc_k = psrc;
        char *pdest_k = pdest;

        char *psrc_m = psrc;
        char *pdest_m = pdest;

        for (m = c6_lb; m <= c6_ub; m++) {
            psrc_k = psrc_m;
            pdest_k = pdest_m;
            for (k = c5_lb; k <= c5_ub; k++) {
                psrc_j = psrc_k;
                pdest_j = pdest_k;
                for (j = c4_lb; j <= c4_ub; j++) {
                    psrc = psrc_j;
                    pdest = pdest_j;
                    for (i = c3_lb; i <= c3_ub; i++) {
                        slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);
                        psrc += nSrcOff_i;
                        pdest += nDestOff_i;
                    }
                    psrc_j += nSrcOff_j;
                    pdest_j += nDestOff_j;
                }
                psrc_k += nSrcOff_k;
                pdest_k += nDestOff_k;
            }
            psrc_m += nSrcOff_m;
            pdest_m += nDestOff_m;
        }
        int counter_val = *counter;
        counter_val += (cm5 * cm4 * cm3 * cm2);
        *counter = counter_val;

    } else if (stride_no == 1) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout6d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4,
                                            tm5, cm5, e_type_size, 2);
        }
        int len = cm2 * cm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm1 - cm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm1;
        bsize *= dm0;
        bsize *= e_type_size;

        int nSrcOff_m = dm4 * dm3 * dm2 * dm1 * dm0;
        nSrcOff_m *= e_type_size;

        int nDestOff_m = tm4 * tm3 * tm2 * tm1 * tm0;
        nDestOff_m *= e_type_size;

        int nSrcOff_k = dm3 * dm2 * dm1 * dm0;
        nSrcOff_k *= e_type_size;

        int nDestOff_k = tm3 * tm2 * tm1 * tm0;
        nDestOff_k *= e_type_size;

        int nSrcOff_j = dm2 * dm1 * dm0;
        nSrcOff_j *= e_type_size;

        int nDestOff_j = tm2 * tm1 * tm0;
        nDestOff_j *= e_type_size;

        char *psrc_m = psrc;
        char *pdest_m = pdest;

        char *psrc_k = psrc;
        char *pdest_k = pdest;

        for (m = c6_lb; m <= c6_ub; m++) {
            psrc_k = psrc_m;
            pdest_k = pdest_m;
            for (k = c5_lb; k <= c5_ub; k++) {
                psrc = psrc_k;
                pdest = pdest_k;
                for (j = c4_lb; j <= c4_ub; j++) {
                    slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);
                    psrc += nSrcOff_j;
                    pdest += nDestOff_j;
                }
                psrc_k += nSrcOff_k;
                pdest_k += nDestOff_k;
            }
            psrc_m += nSrcOff_m;
            pdest_m += nDestOff_m;
        }
        int counter_val = *counter;
        counter_val += (cm5 * cm4 * cm3);
        *counter = counter_val;
    } else if (stride_no == 2) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout6d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4,
                                            tm5, cm5, e_type_size, 3);
        }
        int len = cm3 * cm2;
        len *= dm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm2 - cm2;
        stride *= dm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm2;
        bsize *= dm1;
        bsize *= dm0;
        bsize *= e_type_size;

        int nSrcOff_m = dm4 * dm3 * dm2 * dm1 * dm0;
        nSrcOff_m *= e_type_size;

        int nDestOff_m = tm4 * tm3 * tm2 * tm1 * tm0;
        nDestOff_m *= e_type_size;

        int nSrcOff_k = dm3 * dm2 * dm1 * dm0;
        nSrcOff_k *= e_type_size;

        int nDestOff_k = tm3 * tm2 * tm1 * tm0;
        nDestOff_k *= e_type_size;

        char *psrc_m = psrc;
        char *pdest_m = pdest;

        for (m = c6_lb; m <= c6_ub; m++) {
            psrc = psrc_m;
            pdest = pdest_m;
            for (k = c5_lb; k <= c5_ub; k++) {
                slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);

                psrc += nSrcOff_k;
                pdest += nDestOff_k;
            }
            psrc_m += nSrcOff_m;
            pdest_m += nDestOff_m;
        }
        int counter_val = *counter;
        counter_val += (cm5 * cm4);
        *counter = counter_val;

    } else if (stride_no == 3) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout6d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4,
                                            tm5, cm5, e_type_size, 4);
        }
        int len = cm4 * cm3;
        len *= dm2;
        len *= dm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm3 - cm3;
        stride *= dm2;
        stride *= dm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm3;
        bsize *= dm2;
        bsize *= dm1;
        bsize *= dm0;
        bsize *= e_type_size;

        int nSrcOff_m = dm4 * dm3 * dm2 * dm1 * dm0;
        nSrcOff_m *= e_type_size;

        int nDestOff_m = tm4 * tm3 * tm2 * tm1 * tm0;
        nDestOff_m *= e_type_size;

        for (m = c6_lb; m <= c6_ub; m++) {
            slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);

            psrc += nSrcOff_m;
            pdest += nDestOff_m;
        }
        int counter_val = *counter;
        counter_val += cm5;
        *counter = counter_val;

    } else if (stride_no == 4) {
        if (reshape_flag == 1) {
            slave_acemesh_reshape_copyout6d(psrc, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4,
                                            tm5, cm5, e_type_size, 5);
        }
        int len = cm5 * cm4;
        len *= dm3;
        len *= dm2;
        len *= dm1;
        len *= dm0;
        len *= e_type_size;

        int stride = dm4 - cm4;
        stride *= dm3;
        stride *= dm2;
        stride *= dm1;
        stride *= dm0;
        stride *= e_type_size;

        int bsize = cm4;
        bsize *= dm3;
        bsize *= dm2;
        bsize *= dm1;
        bsize *= dm0;
        bsize *= e_type_size;

        slave_acemesh_athread_put(0, psrc, pdest, len, reply, stride, bsize);

        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;

    } else {
        int len = cm5 * dm4 * dm3 * dm2 * dm1 * dm0;
        len *= e_type_size;

        slave_acemesh_athread_put(0, psrc, pdest, len, reply, 0, 0);
        int counter_val = *counter;
        counter_val += 1;
        *counter = counter_val;
    }
}
#ifdef COPY_OLD
void slave_acemesh_copyin1d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int e_type_size, int *reply, int *counter)
{
    slave_acemesh_copyin1d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, e_type_size, reply,
                           counter);
}

void slave_acemesh_copyout1d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                              int c1_lb, int c1_ub, int e_type_size, int *reply, int *counter)
{
    slave_acemesh_copyout1d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, e_type_size, reply,
                            counter);
}

void slave_acemesh_copyin2d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int e_type_size, int *reply, int *counter)
{
    slave_acemesh_copyin2d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub, t2_lb,
                           t2_ub, c2_lb, c2_ub, e_type_size, reply, counter);
}
void slave_acemesh_copyout2d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                              int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                              int c2_lb, int c2_ub, int e_type_size, int *reply, int *counter)
{
    slave_acemesh_copyout2d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                            t2_lb, t2_ub, c2_lb, c2_ub, e_type_size, reply, counter);
}

void slave_acemesh_copyin3d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                             int c3_lb, int c3_ub, int e_type_size, int *reply, int *counter)
{
    slave_acemesh_copyin3d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub, t2_lb,
                           t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub,
                           e_type_size, reply, counter);
}
void slave_acemesh_copyout3d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                              int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                              int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                              int c3_lb, int c3_ub, int e_type_size, int *reply, int *counter)
{
    slave_acemesh_copyout3d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                            t2_lb, t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub,
                            e_type_size, reply, counter);
}
void slave_acemesh_copyin4d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                             int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                             int c4_lb, int c4_ub, int e_type_size, int *reply, int *counter)
{
    slave_acemesh_copyin4d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub, t2_lb,
                           t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub, d4_lb,
                           d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, e_type_size, reply, counter);
}
void slave_acemesh_copyout4d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                              int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                              int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                              int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                              int c4_lb, int c4_ub, int e_type_size, int *reply, int *counter)
{
    slave_acemesh_copyout4d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                            t2_lb, t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub,
                            d4_lb, d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, e_type_size, reply, counter);
}
void slave_acemesh_copyin5d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                             int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                             int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                             int c5_lb, int c5_ub, int e_type_size, int *reply, int *counter)
{
    slave_acemesh_copyin5d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub, t2_lb,
                           t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub, d4_lb,
                           d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, d5_lb, d5_ub, t5_lb, t5_ub, c5_lb,
                           c5_ub, e_type_size, reply, counter);
}
void slave_acemesh_copyout5d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                              int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                              int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                              int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                              int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                              int c5_lb, int c5_ub, int e_type_size, int *reply, int *counter)
{
    slave_acemesh_copyout5d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                            t2_lb, t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub,
                            d4_lb, d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, d5_lb, d5_ub, t5_lb, t5_ub,
                            c5_lb, c5_ub, e_type_size, reply, counter);
}
void slave_acemesh_copyin6d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                             int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                             int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                             int c5_lb, int c5_ub, int d6_lb, int d6_ub, int t6_lb, int t6_ub,
                             int c6_lb, int c6_ub, int e_type_size, int *reply, int *counter)
{
    slave_acemesh_copyin6d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub, t2_lb,
                           t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub, d4_lb,
                           d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, d5_lb, d5_ub, t5_lb, t5_ub, c5_lb,
                           c5_ub, d6_lb, d6_ub, t6_lb, t6_ub, c6_lb, c6_ub, e_type_size, reply,
                           counter);
}
void slave_acemesh_copyout6d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                              int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                              int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                              int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                              int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                              int c5_lb, int c5_ub, int d6_lb, int d6_ub, int t6_lb, int t6_ub,
                              int c6_lb, int c6_ub, int e_type_size, int *reply, int *counter)
{
    slave_acemesh_copyout6d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                            t2_lb, t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub,
                            d4_lb, d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, d5_lb, d5_ub, t5_lb, t5_ub,
                            c5_lb, c5_ub, d6_lb, d6_ub, t6_lb, t6_ub, c6_lb, c6_ub, e_type_size,
                            reply, counter);
}
#else
void slave_acemesh_copyin1d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int e_type_size, int *reply, int *counter,
                             int *dma_bytes)
{
    slave_acemesh_copyin1d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, e_type_size, reply,
                           counter, dma_bytes);
}

void slave_acemesh_copyout1d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                              int c1_lb, int c1_ub, int e_type_size, int *reply, int *counter,
                              int *dma_bytes)
{
    slave_acemesh_copyout1d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, e_type_size, reply,
                            counter, dma_bytes);
}

void slave_acemesh_copyin2d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int e_type_size, int *reply, int *counter,
                             int *dma_bytes)
{
    slave_acemesh_copyin2d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub, t2_lb,
                           t2_ub, c2_lb, c2_ub, e_type_size, reply, counter, dma_bytes);
}
void slave_acemesh_copyout2d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                              int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                              int c2_lb, int c2_ub, int e_type_size, int *reply, int *counter,
                              int *dma_bytes)
{
    slave_acemesh_copyout2d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                            t2_lb, t2_ub, c2_lb, c2_ub, e_type_size, reply, counter, dma_bytes);
}

void slave_acemesh_copyin3d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                             int c3_lb, int c3_ub, int e_type_size, int *reply, int *counter,
                             int *dma_bytes)
{
    slave_acemesh_copyin3d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub, t2_lb,
                           t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub,
                           e_type_size, reply, counter, dma_bytes);
}
void slave_acemesh_copyout3d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                              int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                              int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                              int c3_lb, int c3_ub, int e_type_size, int *reply, int *counter,
                              int *dma_bytes)
{
    slave_acemesh_copyout3d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                            t2_lb, t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub,
                            e_type_size, reply, counter, dma_bytes);
}
void slave_acemesh_copyin4d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                             int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                             int c4_lb, int c4_ub, int e_type_size, int *reply, int *counter,
                             int *dma_bytes)
{
    slave_acemesh_copyin4d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub, t2_lb,
                           t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub, d4_lb,
                           d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, e_type_size, reply, counter,
                           dma_bytes);
}
void slave_acemesh_copyout4d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                              int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                              int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                              int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                              int c4_lb, int c4_ub, int e_type_size, int *reply, int *counter,
                              int *dma_bytes)
{
    slave_acemesh_copyout4d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                            t2_lb, t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub,
                            d4_lb, d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, e_type_size, reply, counter,
                            dma_bytes);
}
void slave_acemesh_copyin5d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                             int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                             int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                             int c5_lb, int c5_ub, int e_type_size, int *reply, int *counter,
                             int *dma_bytes)
{
    slave_acemesh_copyin5d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub, t2_lb,
                           t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub, d4_lb,
                           d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, d5_lb, d5_ub, t5_lb, t5_ub, c5_lb,
                           c5_ub, e_type_size, reply, counter, dma_bytes);
}
void slave_acemesh_copyout5d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                              int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                              int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                              int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                              int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                              int c5_lb, int c5_ub, int e_type_size, int *reply, int *counter,
                              int *dma_bytes)
{
    slave_acemesh_copyout5d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                            t2_lb, t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub,
                            d4_lb, d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, d5_lb, d5_ub, t5_lb, t5_ub,
                            c5_lb, c5_ub, e_type_size, reply, counter, dma_bytes);
}
void slave_acemesh_copyin6d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                             int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                             int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                             int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                             int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                             int c5_lb, int c5_ub, int d6_lb, int d6_ub, int t6_lb, int t6_ub,
                             int c6_lb, int c6_ub, int e_type_size, int *reply, int *counter,
                             int *dma_bytes)
{
    slave_acemesh_copyin6d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub, t2_lb,
                           t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub, d4_lb,
                           d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, d5_lb, d5_ub, t5_lb, t5_ub, c5_lb,
                           c5_ub, d6_lb, d6_ub, t6_lb, t6_ub, c6_lb, c6_ub, e_type_size, reply,
                           counter, dma_bytes);
}
void slave_acemesh_copyout6d_(void *src, void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                              int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                              int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                              int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                              int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                              int c5_lb, int c5_ub, int d6_lb, int d6_ub, int t6_lb, int t6_ub,
                              int c6_lb, int c6_ub, int e_type_size, int *reply, int *counter,
                              int *dma_bytes)
{
    slave_acemesh_copyout6d(src, dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                            t2_lb, t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub,
                            d4_lb, d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, d5_lb, d5_ub, t5_lb, t5_ub,
                            c5_lb, c5_ub, d6_lb, d6_ub, t6_lb, t6_ub, c6_lb, c6_ub, e_type_size,
                            reply, counter, dma_bytes);
}
#endif

void slave_acemesh_copyin2d_adjust(void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                                   int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                                   int c2_lb, int c2_ub, int e_type_size)
{
    int stride_flag = 0;
    int stride_no = 1;
    int reshape_flag = 0;

    int dm0 = d1_ub - d1_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;

    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    }

    if (tm0 != cm0) {
        reshape_flag = 1;
    }
    if (reshape_flag == 0) {
        return;
    }
    if (stride_no == 1) {
        stride_no = 0;
    }

    if (stride_no == 0) {
        slave_acemesh_reshape_copyin2d(dest, tm0, cm0, tm1, cm1, e_type_size, 1);
    }
}

/*from the 3d c array(t3,t2,t1) to the  3d c array(d3,d2,d1) */
/* the corresponding fortran array is (t1,t2,t3) and (d1,d2,d3) respectively */
/* in fact, expand data */
// stride_no starts from 0, it must be >= 1 && <= dim_num - 1
// so,in this case, stride_no is 1 or 2
void slave_acemesh_copyin3d_adjust(void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                                   int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                                   int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                                   int c3_lb, int c3_ub, int e_type_size)
{
    int dm0 = d1_ub - d1_lb + 1;
    int dm1 = d2_ub - d2_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int cm2 = c3_ub - c3_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;
    int tm2 = t3_ub - t3_lb + 1;

    int stride_flag = 0;
    int stride_no = 2;
    int reshape_flag = 0;
    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    } else if (dm1 != cm1) {
        stride_flag = 1;
        stride_no = 1;
    }

    if (tm0 != cm0) {
        reshape_flag = 1;
    } else if (tm1 != cm1) {
        reshape_flag = 1;
    }

    if (reshape_flag == 0) {
        return;
    }
    if (stride_no == 2) {
        stride_no = 1;
    }

    if (stride_no == 0) {
        slave_acemesh_reshape_copyin3d(dest, tm0, cm0, tm1, cm1, tm2, cm2, e_type_size, 1);
    } else if (stride_no == 1) {
        slave_acemesh_reshape_copyin3d(dest, tm0, cm0, tm1, cm1, tm2, cm2, e_type_size, 2);
    }
}
void slave_acemesh_copyin4d_adjust(void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                                   int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                                   int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                                   int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                                   int c4_lb, int c4_ub, int e_type_size)
{
    int dm0 = d1_ub - d1_lb + 1;
    int dm1 = d2_ub - d2_lb + 1;
    int dm2 = d3_ub - d3_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int cm2 = c3_ub - c3_lb + 1;
    int cm3 = c4_ub - c4_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;
    int tm2 = t3_ub - t3_lb + 1;
    int tm3 = t4_ub - t4_lb + 1;

    int stride_flag = 0;
    int stride_no = 3;
    int reshape_flag = 0;

    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    } else if (dm1 != cm1) {
        stride_flag = 1;
        stride_no = 1;
    } else if (dm2 != cm2) {
        stride_flag = 1;
        stride_no = 2;
    }

    if (tm0 != cm0) {
        reshape_flag = 1;
    } else if (tm1 != cm1) {
        reshape_flag = 1;
    } else if (tm2 != cm2) {
        reshape_flag = 1;
    }

    if (reshape_flag == 0) {
        return;
    }
    if (stride_no == 3) {
        stride_no = 2;
    }

    if (stride_no == 0) {
        slave_acemesh_reshape_copyin4d(dest, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, e_type_size,
                                       1);
    } else if (stride_no == 1) {
        slave_acemesh_reshape_copyin4d(dest, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, e_type_size,
                                       2);
    } else if (stride_no == 2) {
        slave_acemesh_reshape_copyin4d(dest, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, e_type_size,
                                       3);
    }
}
void slave_acemesh_copyin5d_adjust(void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                                   int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                                   int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                                   int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                                   int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                                   int c5_lb, int c5_ub, int e_type_size)
{
    int dm0 = d1_ub - d1_lb + 1;
    int dm1 = d2_ub - d2_lb + 1;
    int dm2 = d3_ub - d3_lb + 1;
    int dm3 = d4_ub - d4_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int cm2 = c3_ub - c3_lb + 1;
    int cm3 = c4_ub - c4_lb + 1;
    int cm4 = c5_ub - c5_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;
    int tm2 = t3_ub - t3_lb + 1;
    int tm3 = t4_ub - t4_lb + 1;
    int tm4 = t5_ub - t5_lb + 1;

    int stride_flag = 0;
    int stride_no = 4;
    int reshape_flag = 0;
    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    } else if (dm1 != cm1) {
        stride_flag = 1;
        stride_no = 1;
    } else if (dm2 != cm2) {
        stride_flag = 1;
        stride_no = 2;
    } else if (dm3 != cm3) {
        stride_flag = 1;
        stride_no = 3;
    }

    if (tm0 != cm0) {
        reshape_flag = 1;
    } else if (tm1 != cm1) {
        reshape_flag = 1;
    } else if (tm2 != cm2) {
        reshape_flag = 1;
    } else if (tm3 != cm3) {
        reshape_flag = 1;
    }

    if (reshape_flag == 0) {
        return;
    }

    if (stride_no == 0) {
        slave_acemesh_reshape_copyin5d(dest, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4,
                                       e_type_size, 1);
    } else if (stride_no == 1) {
        slave_acemesh_reshape_copyin5d(dest, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4,
                                       e_type_size, 2);
    } else if (stride_no == 2) {
        slave_acemesh_reshape_copyin5d(dest, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4,
                                       e_type_size, 3);
    } else if (stride_no == 3) {
        slave_acemesh_reshape_copyin5d(dest, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4,
                                       e_type_size, 4);
    }
}
void slave_acemesh_copyin6d_adjust(void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                                   int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb, int t2_ub,
                                   int c2_lb, int c2_ub, int d3_lb, int d3_ub, int t3_lb, int t3_ub,
                                   int c3_lb, int c3_ub, int d4_lb, int d4_ub, int t4_lb, int t4_ub,
                                   int c4_lb, int c4_ub, int d5_lb, int d5_ub, int t5_lb, int t5_ub,
                                   int c5_lb, int c5_ub, int d6_lb, int d6_ub, int t6_lb, int t6_ub,
                                   int c6_lb, int c6_ub, int e_type_size)
{
    int dm0 = d1_ub - d1_lb + 1;
    int dm1 = d2_ub - d2_lb + 1;
    int dm2 = d3_ub - d3_lb + 1;
    int dm3 = d4_ub - d4_lb + 1;
    int dm4 = d5_ub - d5_lb + 1;
    int cm0 = c1_ub - c1_lb + 1;
    int cm1 = c2_ub - c2_lb + 1;
    int cm2 = c3_ub - c3_lb + 1;
    int cm3 = c4_ub - c4_lb + 1;
    int cm4 = c5_ub - c5_lb + 1;
    int cm5 = c6_ub - c6_lb + 1;
    int tm0 = t1_ub - t1_lb + 1;
    int tm1 = t2_ub - t2_lb + 1;
    int tm2 = t3_ub - t3_lb + 1;
    int tm3 = t4_ub - t4_lb + 1;
    int tm4 = t5_ub - t5_lb + 1;
    int tm5 = t6_ub - t6_lb + 1;
    int stride_flag = 0;
    int stride_no = 5;
    int reshape_flag = 0;

    if (dm0 != cm0) {
        stride_flag = 1;
        stride_no = 0;
    } else if (dm1 != cm1) {
        stride_flag = 1;
        stride_no = 1;
    } else if (dm2 != cm2) {
        stride_flag = 1;
        stride_no = 2;
    } else if (dm3 != cm3) {
        stride_flag = 1;
        stride_no = 3;
    } else if (dm4 != cm4) {
        stride_flag = 1;
        stride_no = 4;
    }
    if (tm0 != cm0) {
        reshape_flag = 1;
    } else if (tm1 != cm1) {
        reshape_flag = 1;
    } else if (tm2 != cm2) {
        reshape_flag = 1;
    } else if (tm3 != cm3) {
        reshape_flag = 1;
    } else if (tm4 != cm4) {
        reshape_flag = 1;
    }

    if (reshape_flag == 0) {
        return;
    }

    if (stride_no == 5) {
        stride_no = 4;
    }

    if (stride_no == 0) {
        slave_acemesh_reshape_copyin6d(dest, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4, tm5,
                                       cm5, e_type_size, 1);
    } else if (stride_no == 1) {
        slave_acemesh_reshape_copyin6d(dest, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4, tm5,
                                       cm5, e_type_size, 2);
    } else if (stride_no == 2) {
        slave_acemesh_reshape_copyin6d(dest, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4, tm5,
                                       cm5, e_type_size, 3);
    } else if (stride_no == 3) {
        slave_acemesh_reshape_copyin6d(dest, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4, tm5,
                                       cm5, e_type_size, 4);
    } else if (stride_no == 4) {
        slave_acemesh_reshape_copyin6d(dest, tm0, cm0, tm1, cm1, tm2, cm2, tm3, cm3, tm4, cm4, tm5,
                                       cm5, e_type_size, 5);
    }
}
void slave_acemesh_copyin2d_adjust_(void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                                    int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb,
                                    int t2_ub, int c2_lb, int c2_ub, int e_type_size)
{
    slave_acemesh_copyin2d_adjust(dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                                  t2_lb, t2_ub, c2_lb, c2_ub, e_type_size);
}
void slave_acemesh_copyin3d_adjust_(void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                                    int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb,
                                    int t2_ub, int c2_lb, int c2_ub, int d3_lb, int d3_ub,
                                    int t3_lb, int t3_ub, int c3_lb, int c3_ub, int e_type_size)
{
    slave_acemesh_copyin3d_adjust(dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                                  t2_lb, t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb,
                                  c3_ub, e_type_size);
}

void slave_acemesh_copyin4d_adjust_(void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                                    int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb,
                                    int t2_ub, int c2_lb, int c2_ub, int d3_lb, int d3_ub,
                                    int t3_lb, int t3_ub, int c3_lb, int c3_ub, int d4_lb,
                                    int d4_ub, int t4_lb, int t4_ub, int c4_lb, int c4_ub,
                                    int e_type_size)
{
    slave_acemesh_copyin4d_adjust(dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                                  t2_lb, t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb,
                                  c3_ub, d4_lb, d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, e_type_size);
}

void slave_acemesh_copyin5d_adjust_(void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                                    int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb,
                                    int t2_ub, int c2_lb, int c2_ub, int d3_lb, int d3_ub,
                                    int t3_lb, int t3_ub, int c3_lb, int c3_ub, int d4_lb,
                                    int d4_ub, int t4_lb, int t4_ub, int c4_lb, int c4_ub,
                                    int d5_lb, int d5_ub, int t5_lb, int t5_ub, int c5_lb,
                                    int c5_ub, int e_type_size)
{
    slave_acemesh_copyin5d_adjust(dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub,
                                  t2_lb, t2_ub, c2_lb, c2_ub, d3_lb, d3_ub, t3_lb, t3_ub, c3_lb,
                                  c3_ub, d4_lb, d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, d5_lb, d5_ub,
                                  t5_lb, t5_ub, c5_lb, c5_ub, e_type_size);
}

void slave_acemesh_copyin6d_adjust_(void *dest, int d1_lb, int d1_ub, int t1_lb, int t1_ub,
                                    int c1_lb, int c1_ub, int d2_lb, int d2_ub, int t2_lb,
                                    int t2_ub, int c2_lb, int c2_ub, int d3_lb, int d3_ub,
                                    int t3_lb, int t3_ub, int c3_lb, int c3_ub, int d4_lb,
                                    int d4_ub, int t4_lb, int t4_ub, int c4_lb, int c4_ub,
                                    int d5_lb, int d5_ub, int t5_lb, int t5_ub, int c5_lb,
                                    int c5_ub, int d6_lb, int d6_ub, int t6_lb, int t6_ub,
                                    int c6_lb, int c6_ub, int e_type_size)
{
    slave_acemesh_copyin6d_adjust(
        dest, d1_lb, d1_ub, t1_lb, t1_ub, c1_lb, c1_ub, d2_lb, d2_ub, t2_lb, t2_ub, c2_lb, c2_ub,
        d3_lb, d3_ub, t3_lb, t3_ub, c3_lb, c3_ub, d4_lb, d4_ub, t4_lb, t4_ub, c4_lb, c4_ub, d5_lb,
        d5_ub, t5_lb, t5_ub, c5_lb, c5_ub, d6_lb, d6_ub, t6_lb, t6_ub, c6_lb, c6_ub, e_type_size);
}

/*
void * slave_acemesh_ldm_malloc(int size)
{
  void * addr;
  addr=ldm_malloc(size);
  return addr;
}

void slave_acemesh_ldm_free(void *addr, int size)
{
  ldm_free(addr,size);
}

void* slave_acemesh_ldm_malloc_(int size)
{
  void * addr;
  addr=ldm_malloc(size);
  return addr;
}

void slave_acemesh_ldm_free_(void *addr, int size)
{
  ldm_free(addr,size);
}
int slave_acemesh_get_allocatable_size()
{
  return get_allocatable_size();
}

int slave_acemesh_get_allocatable_size_()
{
  return get_allocatable_size();
}
*/
